commit 4fd09e314b38555b567256aa025e13824b22e78b Author: pezcurrel Date: Tue Dec 31 06:45:00 2024 +0100 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..cd7dfdf --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +```text +[[[ SYNOPSIS ]]] + + anagram [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 dump master», possibly piping its output +into «aspell -l expand 4», and doing some cleanup with «grep», +«sed» and the likes. + +[[[ ACTIONS ]]] + + search + Search for possible anagrams of «word» into «dictionary file». + + combine + Print all possible combinations of characters in «word». + + genadict + 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 for details. + +``` diff --git a/anagram b/anagram new file mode 100755 index 0000000..9f591c4 --- /dev/null +++ b/anagram @@ -0,0 +1,158 @@ +#!/bin/php +null, + 'inpword'=>null, + 'ifp'=>null, + 'ofp'=>null +]; + +$help= +"[[[ SYNOPSIS ]]] + + {$SCRIPTNAME} [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 dump master», possibly piping its output +into «aspell -l expand 4», and doing some cleanup with «grep», +«sed» and the likes. + +[[[ ACTIONS ]]] + + search + Search for possible anagrams of «word» into «dictionary file». + + combine + Print all possible combinations of characters in «word». + + genadict + 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 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); +} + +?> diff --git a/dicts.zip b/dicts.zip new file mode 100644 index 0000000..0c9ce1e Binary files /dev/null and b/dicts.zip differ diff --git a/makedicts.sh b/makedicts.sh new file mode 100755 index 0000000..14d5792 --- /dev/null +++ b/makedicts.sh @@ -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