1
0
Fork 0
forked from Jones/anagram
anagram/anagram

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);
}
?>