First commit

This commit is contained in:
pezcurrel 2024-12-31 06:45:00 +01:00
commit 4fd09e314b
4 changed files with 201 additions and 0 deletions

38
README.md Normal file
View file

@ -0,0 +1,38 @@
```text
[[[ SYNOPSIS ]]]
anagram <action> [action arguments]
[[[ DESCRIPTION ]]]
This is anagram v0.1.1, 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.
```

158
anagram Executable file
View file

@ -0,0 +1,158 @@
#!/bin/php
<?php
$SCRIPTNAME='anagram';
$SCRIPTVERSION='0.1.1';
$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') {
$dict=@file($conf['ifp'],FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);
if ($dict===false) dieyoung("Error: could not read «{$conf['ifp']}».\n",1);
foreach ($dict as $key=>$word)
$dict[$key]=mb_strtolower($word,'UTF-8');
$anagrams=[];
foreach ($dict as $key=>$word) {
$sword=sortword($word);
if (!array_key_exists($sword,$anagrams) || !in_array($word,$anagrams[$sword]))
$anagrams[$sword][]=$word;
}
}
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";
} else {
echo "Found no anagrams for «{$conf['inpword']}».\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);
}
?>

BIN
dicts.zip Normal file

Binary file not shown.

5
makedicts.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
aspell -d it dump master | grep -vi -P '^copyright[a-z]' | sed -e 's/\/.*$//' > italiano.txt
aspell -d it dump master | aspell -l it expand 4 | grep -vi -P '^copyright[a-z]' | grep -v "'" | sed -e 's/^[^ ]\+ //' -e 's/ .*//' > italiano_espanso.txt
aspell -d en dump master | grep -v "'" | sed -e 's/\/.*$//' > english.txt