forked from Jones/anagram
157 lines
4.7 KiB
PHP
Executable file
157 lines
4.7 KiB
PHP
Executable file
#!/bin/php
|
|
<?php
|
|
|
|
$SCRIPTNAME='anagram';
|
|
$SCRIPTVERSION='0.1.2';
|
|
$SCRIPTURL='https://git.lattuga.net/Jones/anagram';
|
|
|
|
$conf=[
|
|
'action'=>null,
|
|
'inpword'=>null,
|
|
'ifp'=>null,
|
|
'ofp'=>null
|
|
];
|
|
|
|
$help=
|
|
"[[[ SYNOPSIS ]]]
|
|
|
|
{$SCRIPTNAME} <action> [action arguments]
|
|
|
|
[[[ DESCRIPTION ]]]
|
|
|
|
This is {$SCRIPTNAME} v{$SCRIPTVERSION}, a CLI PHP script that can anagram words and create
|
|
«anagram dictionaries» based on input dictionaries.
|
|
Dictionaries need to be text files with one word per line, like those you can
|
|
find inside the included «dicts.zip» file.
|
|
You can create other dictionaries with the «aspell» tool (http://aspell.net/)
|
|
by running «aspell -d <langcode> dump master», possibly piping its output
|
|
into «aspell -l <langcode> expand 4», and doing some cleanup with «grep»,
|
|
«sed» and the likes.
|
|
|
|
[[[ ACTIONS ]]]
|
|
|
|
search <word> <dictionary file>
|
|
Search for possible anagrams of «word» into «dictionary file».
|
|
|
|
combine <word>
|
|
Print all possible combinations of characters in «word».
|
|
|
|
genadict <dictionary file> <output file>
|
|
Use «dictionary file» to generate an «anagrams dictionary» and save it into
|
|
«output file».
|
|
|
|
help
|
|
Show this help text and exit. Requires no arguments.
|
|
|
|
[[[ DISCLAIMER AND LICENSE ]]]
|
|
|
|
This program comes with ABSOLUTELY NO WARRANTY; for details see the source.
|
|
This is free software, and you are welcome to redistribute it under certain
|
|
conditions; see <http://www.gnu.org/licenses/> for details.\n";
|
|
|
|
for ($i=1; $i<$argc; $i++) {
|
|
if ($argv[$i]=='help') {
|
|
echo $help;
|
|
exit(0);
|
|
} elseif ($argv[$i]=='makereadme') {
|
|
file_put_contents(__DIR__.'/README.md',"```text\n{$help}\n```\n");
|
|
exit(0);
|
|
} elseif ($argv[$i]=='combine') {
|
|
if (!array_key_exists($i+1,$argv))
|
|
dieyoung("Error: «combine» action requires a word as argument.\n",1);
|
|
$conf['action']='combine';
|
|
$conf['inpword']=$argv[$i+1];
|
|
$i++;
|
|
} elseif ($argv[$i]=='search') {
|
|
if (!array_key_exists($i+1,$argv) || !array_key_exists($i+2,$argv))
|
|
dieyoung("Error: «search» action requires two arguments: the word to search and a dictionary file.\n",1);
|
|
$conf['action']='search';
|
|
$conf['inpword']=$argv[$i+1];
|
|
$conf['ifp']=$argv[$i+2];
|
|
$i+=2;
|
|
} elseif ($argv[$i]=='genadict') {
|
|
if (!array_key_exists($i+1,$argv) || !array_key_exists($i+2,$argv))
|
|
dieyoung("Error: «genadict» action requires two arguments: a dictionary file and an output file.\n",1);
|
|
$conf['action']='genadict';
|
|
$conf['ifp']=$argv[$i+1];
|
|
$conf['ofp']=$argv[$i+2];
|
|
$i+=2;
|
|
} else {
|
|
dieyoung("Error: «{$argv[$i]}» is not a valid action (use «help» to read help).\n",1);
|
|
}
|
|
}
|
|
|
|
if (is_null($conf['action'])) dieyoung("Error: you have not specified any action.\n",1);
|
|
if (($conf['action']==='genadict' || $conf['action']==='search') && is_null($conf['ifp'])) dieyoung("Error: you have not specified a dictionary file.\n",1);
|
|
if ($conf['action']==='genadict' && is_null($conf['ofp'])) dieyoung("Error: you have not specified an output file.\n",1);
|
|
if ($conf['action']==='search' && is_null($conf['inpword'])) dieyoung("Error: you have not specified a word to anagram.\n",1);
|
|
|
|
if ($conf['action']==='genadict' || $conf['action']==='search') {
|
|
$buff=@file($conf['ifp'],FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);
|
|
if ($buff===false) dieyoung("Error: could not read «{$conf['ifp']}».\n",1);
|
|
foreach ($buff as $key=>$word)
|
|
$buff[$key]=mb_strtolower($word,'UTF-8');
|
|
$anagrams=[];
|
|
foreach ($buff as $key=>$word) {
|
|
$sword=sortword($word);
|
|
if (!array_key_exists($sword,$anagrams) || !in_array($word,$anagrams[$sword]))
|
|
$anagrams[$sword][]=$word;
|
|
}
|
|
unset($buff);
|
|
}
|
|
|
|
if ($conf['action']==='genadict') {
|
|
$fo=@fopen($conf['ofp'],'w');
|
|
if ($fo===false) dieyoung("Error: could not open «{$conf['ofp']}» in write mode.\n",1);
|
|
foreach ($anagrams as $sword=>$words) {
|
|
if (count($words)>1) {
|
|
sort($words);
|
|
$words=implode(' ',$words);
|
|
fwrite($fo,"{$words}\n");
|
|
}
|
|
}
|
|
fclose($fo);
|
|
} elseif ($conf['action']==='search') {
|
|
$sword=sortword($conf['inpword']);
|
|
if (array_key_exists($sword,$anagrams)) {
|
|
$buff=$anagrams[$sword];
|
|
if (!in_array($conf['inpword'],$buff))
|
|
$buff[]=$conf['inpword'];
|
|
sort($buff);
|
|
if (count($buff)>1)
|
|
echo implode(' ',$buff)."\n";
|
|
}
|
|
} elseif ($conf['action']==='combine') {
|
|
$conf['inpword']=mb_str_split($conf['inpword']);
|
|
combine($conf['inpword'],count($conf['inpword']));
|
|
}
|
|
exit(0);
|
|
|
|
|
|
function combine($arr,$rounds,$round=0) {
|
|
global $word;
|
|
foreach ($arr as $key=>$val) {
|
|
$word[$round]=$val;
|
|
if ($round==$rounds-1) {
|
|
echo implode('',$word)."\n";
|
|
} else {
|
|
$narr=$arr;
|
|
unset($narr[$key]);
|
|
combine($narr,$rounds,$round+1);
|
|
}
|
|
}
|
|
}
|
|
|
|
function sortword($word) {
|
|
$word=mb_str_split($word,1,'UTF-8');
|
|
sort($word);
|
|
$word=implode('',$word);
|
|
return $word;
|
|
}
|
|
|
|
function dieyoung($msg,$ec) {
|
|
fwrite(STDERR,$msg);
|
|
die($ec);
|
|
}
|
|
|
|
?>
|