Semordnilap: Difference between revisions
SuperCollider solution to Rosetta Code TASK: Semordnilap
(Updated to work with Nim 1.4. Replaced "sort" with the easier "sortByIt".) |
Music Coder (talk | contribs) (SuperCollider solution to Rosetta Code TASK: Semordnilap) |
||
(32 intermediate revisions by 20 users not shown) | |||
Line 1:
{{task}}
A [
Example: ''lager'' and ''regal''
<br><br>
;Task
This task does not consider semordnilap phrases, only single words.
Using only words from <u>[http://wiki.puzzlers.org/pub/wordlists/unixdict.txt this list]</u>, report the total number of unique semordnilap pairs, and print 5 examples.
Two matching semordnilaps, such as ''lager'' and ''regal'', should be counted as one unique pair.
(Note that the word "semordnilap" is not in the above dictionary.)
Line 16 ⟶ 18:
{{trans|Python}}
<
V revlist = wordset.map(word -> reversed(word))
V pairs = Set(zip(wordset, revlist).filter((wrd, rev) -> wrd < rev & rev C :wordset))
print(pairs.len)
print(sorted(Array(pairs), key' p -> (p[0].len, p))[(len)-5..])</
{{out}}
Line 31 ⟶ 33:
=={{header|8th}}==
We're using a map to keep track of what's been seen, and an array to store the results. We load the "unixdict.txt" as an "asset", meaning a file stored alongside the program code:
<syntaxhighlight lang="forth">
[] var, results
Line 49 ⟶ 51:
a:shuffle
( a:shift dup . " is the reverse of " . s:rev . cr ) 5 times bye
</syntaxhighlight>
{{out}}
Line 65 ⟶ 67:
Before tackling the real problem, we specify a package String_Vectors and a class String_Vectors.Vec, to store the list of words in the dictionary:
<
package String_Vectors is
Line 83 ⟶ 85:
-- checks if Word is in List(Start .. Stop);
-- requirement: the words in List are sorted alphabetically
end String_Vectors;</
The specified class String_Vectors.Vec has been derived from Ada.Containers.Indefinite_Vectors.Vector and provides two additional primitive operations Read and Is_In. Here is the implementation:
<
function Is_In(List: Vec;
Line 121 ⟶ 123:
end Read;
end String_Vectors;</
This is the main program:
<
procedure Semordnilap is
Line 154 ⟶ 156:
Ada.Text_IO.New_Line;
Ada.Text_IO.Put("pairs found:" & Integer'Image(Semi_Counter));
end Semordnilap;</
{{out}}
Line 167 ⟶ 169:
=={{header|Aime}}==
<
record r;
file f;
Line 187 ⟶ 189:
}
o_form("Semordnilap pairs: ~\n", p);</
{{out}}
<pre>ca ac
Line 199 ⟶ 201:
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
The Algol 68 G "read" PRAGMA is used to include the associative array code from Associative_array/Iteration.
<
# use the associative array in the Associate array/iteration task #
PR read "aArray.a68" PR
Line 260 ⟶ 262:
close( input file );
print( ( whole( semordnilap count, 0 ), " semordnilaps found", newline ) )
FI</
{{out}}
<pre>
Line 272 ⟶ 274:
=={{header|Arturo}}==
<
pairs: []
loop words 'wrd [
Line 284 ⟶ 286:
unique 'pairs
print map 1..5 => [sample pairs]</
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<
FileRead, dict, unixdict.txt
Line 309 ⟶ 311:
r := A_LoopField . r
return r
}</
{{out}}
<pre>5 Examples:
Line 322 ⟶ 324:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f SEMORDNILAP.AWK unixdict.txt
{ arr[$0]++ }
Line 343 ⟶ 345:
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
Line 356 ⟶ 358:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
Sort% = FN_sortinit(0,0)
Line 405 ⟶ 407:
SWAP P%?I%, L%?(P%-I%)
NEXT
= A$</
{{out}}
<pre>
Line 417 ⟶ 419:
=={{header|Bracmat}}==
<
& new$hash:?H
& 0:?p
Line 440 ⟶ 442:
& out$(semordnilap !N dnuoF)
)
);</
{{out}}
<pre>tv vt
Line 451 ⟶ 453:
=={{header|C}}==
<
#include <stdlib.h>
#include <alloca.h> /* stdlib.h might not have obliged. */
Line 516 ⟶ 518:
printf("Semordnilap pairs: %d\n", sem);
return 0;
}</
{{out}}
Line 527 ⟶ 529:
=={{header|C sharp}}==
<
using System.Net;
using System.Collections.Generic;
Line 565 ⟶ 567:
private static string Reversed(string value) => new string(value.Reverse().ToArray());
}</
{{out}}
<pre>
Line 577 ⟶ 579:
=={{header|C++}}==
<
#include <iostream>
#include <set>
Line 604 ⟶ 606:
} else
return 1; // couldn't open input file
}</
{{out}}
<pre>
Line 617 ⟶ 619:
=={{header|Clojure}}==
<
(:require [clojure.string :as str])
[clojure.java.io :as io ]))
Line 640 ⟶ 642:
dict-file)
(dorun (->> semordnilaps shuffle (take 5) sort (map println)))</
{{out}}
Line 651 ⟶ 653:
=={{header|Common Lisp}}==
<
(let ((word-map (make-hash-table :test 'equal)))
(loop for word in word-list do
Line 671 ⟶ 673:
for word in words
do (print word)))
(values))</
{{out}}
<pre>* (main)
Line 682 ⟶ 684:
=={{header|Crystal}}==
<
UNIXDICT = File.read("unixdict.txt").lines
Line 699 ⟶ 701:
# print out the size, and 5 random pairs
puts final_results.size, final_results.sample(5)
</syntaxhighlight>
{{out}}
Line 709 ⟶ 711:
=={{header|D}}==
===Simple Imperative Version===
<
import std.stdio, std.file, std.string, std.algorithm;
Line 727 ⟶ 729:
writeln("\nSemordnilap pairs: ", pairCount);
}</
{{out}}
<pre>ca ac
Line 738 ⟶ 740:
===A More Functional Version===
<
import std.stdio, std.file, std.algorithm, std.string, std.range;
Line 746 ⟶ 748:
.zip(0.repeat).assocArray;
writeln(pairs.length, "\n", pairs.byKey.take(5));
}</
{{out}}
<pre>158
Line 755 ⟶ 757:
{{libheader| System.StrUtils}}
{{libheader| System.Diagnostics}}
<syntaxhighlight lang="delphi">
program Semordnilap;
Line 877 ⟶ 879:
end.
</syntaxhighlight>
{{out}}
Line 897 ⟶ 899:
We use the '''words''' library, and the french dictionary delivered with EchoLisp.
<
(lib 'struct)
(lib 'sql)
Line 923 ⟶ 925:
(writeln 'pairs '→ (length semordnilap))
(writeln 'longest '→ (take semordnilap 5)))
</syntaxhighlight>
{{out}}
<pre>
(task)
pairs → 345
longest → (rengager tresser strasse reveler retrace)
</pre>
=={{header|Eiffel}}==
First the programm reads the wordlist into an array.
Then it mirrors each word and searchs for it across the array using binary search.
<syntaxhighlight lang="eiffel">
class
SEMORDNILAP
Line 1,014 ⟶ 1,017:
end
</syntaxhighlight>
Test:
<syntaxhighlight lang="eiffel">
class
APPLICATION
Line 1,051 ⟶ 1,054:
end
</syntaxhighlight>
{{out}}
<pre>
Line 1,063 ⟶ 1,066:
=={{header|Elixir}}==
<
|> Enum.map(&String.strip/1)
|> Enum.group_by(&min(&1, String.reverse &1))
Line 1,069 ⟶ 1,072:
|> Enum.filter(&(length &1) == 2)
IO.puts "Semordnilap pair: #{length(words)}"
IO.inspect Enum.take(words,5)</
{{out}}
Line 1,080 ⟶ 1,083:
=={{header|Erlang}}==
{{trans|Clojure}}
<
main([]) -> main(["unixdict.txt"]);
Line 1,114 ⟶ 1,117:
[X||{_,X} <- lists:sort([ {random:uniform(), N} || N <- List])].
chop(L) -> [_|T] = lists:reverse(L), lists:reverse(T).</
{{out}}
Line 1,126 ⟶ 1,129:
=={{header|F_Sharp|F#}}==
Using a mutable dictionary.
<
let seen = new System.Collections.Generic.Dictionary<string,bool>()
Line 1,142 ⟶ 1,145:
let s = Seq.toList sems
printfn "%d" s.Length
for i in 0 .. 4 do printfn "%A" s.[i]</
{{out}}
<pre>158
Line 1,152 ⟶ 1,155:
=={{header|Factor}}==
<
io.encodings.utf8 io.files kernel literals locals make
prettyprint random sequences ;
Line 1,172 ⟶ 1,175:
]
] H{ } make >alist
[ length "%d semordnilap pairs.\n" printf ] [ 5 sample . ] bi</
{{out}}
<pre>
Line 1,199 ⟶ 1,202:
The code uses two Gforth-specific words: EXECUTE-PARSING (implementable in standard Forth, but not easy) for allowing to provide the name of the defined word on the stack; and FIND-NAME-IN to look up the reversed word (could be replaced with a use of the standard SEARCH-WORDLIST, but the code would become a little more complicated).
<
wordlist constant dict
Line 1,235 ⟶ 1,238:
0 ' nt-semicheck dict traverse-wordlist cr .
cr bye
</syntaxhighlight>
{{out}}
Line 1,253 ⟶ 1,256:
<
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Sun May 19 21:50:08
Line 1,371 ⟶ 1,374:
end program Semordnilap
</syntaxhighlight>
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
Line 1,453 ⟶ 1,456:
Print : Print "Hit any key to end program"
Sleep
End</
{{out}}
<pre>Start reading unixdict.txt ... Done
Line 1,470 ⟶ 1,473:
=={{header|Go}}==
<
import (
Line 1,527 ⟶ 1,530:
fmt.Println(" ", e)
}
}</
{{out}}
<pre>
Line 1,540 ⟶ 1,543:
=={{header|Groovy}}==
<
def words = [] as Set
def semordnilaps = []
Line 1,548 ⟶ 1,551:
}
semordnilaps
}</
Test Code
<
println "Found ${semordnilaps.size()} semordnilap words"
semordnilaps[0..<5].each { println "$it -> ${it.reverse()}" } </
{{out}}
<pre>Found 158 semordnilap words
Line 1,562 ⟶ 1,565:
=={{header|Haskell}}==
<
semordnilaps
Line 1,578 ⟶ 1,581:
let l = semordnilaps (lines s)
print $ length l
mapM_ (print . ((,) <*> reverse)) $ take 5 (filter ((4 <) . length) l)</
{{out}}
<pre>158
Line 1,590 ⟶ 1,593:
The following solution works in both Icon and Unicon:
<
words := set()
found := 0
Line 1,601 ⟶ 1,604:
write("\nFound ",found," semordnilap words")
end
</syntaxhighlight>
Sample run with unixdict:
Line 1,620 ⟶ 1,623:
We find all semordnilaps by filtering only words which, when reversed, are a member of the set of dictionary words and are not palindromes. We then find only unique semordnilaps by pairing them with their reversed instance, sorting each pair, and eliminating duplicates pairs:
<
unixdict=: <;._2 freads 'unixdict.txt'
#semordnilaps=: ~. /:~"1 (,. |.&.>) (#~ isSemordnilap) unixdict
158</
We see that there are 158 semordnilaps.
Line 1,629 ⟶ 1,632:
Here's 5 of them, picked arbitrarily:
<syntaxhighlight lang="text"> (5?.158) { semordnilaps
┌────┬────┐
│kay │yak │
Line 1,640 ⟶ 1,643:
├────┼────┤
│caw │wac │
└────┴────┘</
=={{header|Java}}==
{{trans|D}}
{{works with|Java|7+}}
<
import java.util.*;
Line 1,664 ⟶ 1,667:
System.out.println("\nSemordnilap pairs found: " + count);
}
}</
<pre>ca ac
dab bad
Line 1,676 ⟶ 1,679:
===Node.js===
{{trans|Clojure}}
<
var fs = require('fs');
var sys = require('sys');
Line 1,715 ⟶ 1,718:
for (var i=0; i<5; ++i) {
sys.puts(semordnilaps[indices[i]]);
}</
===Rhino===
{{works with|Rhino|1.7}}
<
importPackage (java.io)
Line 1,757 ⟶ 1,760:
for (var i=0; i<5; ++i) {
print(semordnilaps[indices[i]]);
}</
{{out}}
Line 1,769 ⟶ 1,772:
===macOS JavaScript for Automation===
{{Trans|Python}}
<
'use strict';
Line 1,828 ⟶ 1,831:
// MAIN ---
return main();
})();</
{{Out}}
<pre>158
Line 1,850 ⟶ 1,853:
* time /usr/local/bin/jq -M -s -R -r -f semordnilap.jq unixdict.txt
user 0m0.440s; sys 0m0.010s
<syntaxhighlight lang="jq">
# Produce a stream
def report:
Line 1,861 ⟶ 1,864:
| (. < $rev and $dict[$rev]) );
[report] | (.[0:5][], "length = \(length)")</
{{Out}}
able
Line 1,871 ⟶ 1,874:
=={{header|Julia}}==
<
inter = intersect(raw,map(reverse,raw)) #find the matching strings/revstrings
res = String[b == 1 && a != reverse(a) && a < reverse(a) ? a : reverse(a) for a in inter, b in 1:2] #create pairs
res = res[res[:,1] .!= res[:,2],:] #get rid of duplicates, palindromes</
<pre>julia> length(res[:,1])
158
Line 1,888 ⟶ 1,891:
=={{header|Kotlin}}==
{{trans|D}}
<
import java.io.File
Line 1,898 ⟶ 1,901:
println("Found ${pairs.size} semordnilap pairs")
println(pairs.take(5))
}</
{{out}}
Line 1,905 ⟶ 1,908:
[(able, elba), (abut, tuba), (ac, ca), (ah, ha), (al, la)]
</pre>
=={{header|Ksh}}==
<syntaxhighlight lang="ksh">
#!/bin/ksh
# Semordnilap
# # Variables:
#
integer MIN_WORD_LEN=1 TRUE=1 FALSE=0
dict='/home/ostrande/prj/roscode/unixdict.txt'
integer i j=0 k=0
typeset -A word
# # Functions:
#
# # Function _flipit(string) - return flipped string
#
function _flipit {
typeset _buf ; _buf="$1"
typeset _tmp ; unset _tmp
for (( _i=$(( ${#_buf}-1 )); _i>=0; _i-- )); do
_tmp="${_tmp}${_buf:${_i}:1}"
done
echo "${_tmp}"
}
# # Function _isword(word, wordlist) - return 1 if word in wordlist
#
function _isword {
typeset _word ; _word="$1"
typeset _wordlist ; nameref _wordlist="$2"
[[ ${_word} == @(${_wordlist}) ]] && return $TRUE
return $FALSE
}
######
# main #
######
# # Due to the large number of words in unixdist.txt subgroup by 1st letter and length
# # only accept words containing alpha chars and > 1 chars
#
while read; do
[[ $REPLY != *+(\W)* ]] && [[ $REPLY != *+(\d)* ]] && \
(( ${#REPLY} > MIN_WORD_LEN )) && word[${REPLY:0:1}][${#REPLY}]+=( $REPLY )
done < ${dict}
print Examples:
for fl in ${!word[*]}; do # Over $fl first letter
for len in ${!word[${fl}][*]}; do # Over $len word length
for ((i=0; i<${#word[${fl}][${len}][*]}; i++)); do
Word=${word[${fl}][${len}][i]} # dummy
Try=$(_flipit ${Word})
if [[ ${Try} != ${Word} ]]; then # no palindromes
unset words
oldIFS="$IFS" ; IFS='|' ; words=${word[${Try:0:1}][${#Try}][*]} ; IFS="${oldIFS}"
_isword "${Try}" words
if (( $? )); then
if [[ ${Try} != @(${uniq%\|*}) ]]; then
((++j))
(( ${#Word} >= 5 )) && (( k<=5 )) && print $((++k)). ${Word} ${Try}
uniq+="${Try}|${Word}|"
fi
fi
fi
done
done
done
echo ; print ${j} pairs found.</syntaxhighlight>
{{out}}<pre>
Examples:
1. damon nomad
2. kramer remark
3. lager regal
4. leper repel
5. lever revel
158 pairs found.</pre>
=={{header|Lasso}}==
<
words = string(include_url('http://www.puzzlers.org/pub/wordlists/unixdict.txt')) -> split('\n'),
semordnilaps = array,
Line 1,935 ⟶ 2,021:
#found_size
'<br />'
#examples</
{{out}}
<pre>Total found: 158
Line 1,941 ⟶ 2,027:
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
print "Loading dictionary."
open "unixdict.txt" for input as #1
Line 1,986 ⟶ 2,072:
Next i
End Function
</syntaxhighlight>
{{out}}
<pre>
Line 1,999 ⟶ 2,085:
=={{header|Lua}}==
<
-- allow dictionary file and sample size to be specified on command line
local dictfile = arg[1] or "unixdict.txt"
Line 2,032 ⟶ 2,118:
semordnilaps[j] = nil
print(f .. " -> " .. r)
end</
{{out}}
Line 2,043 ⟶ 2,129:
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module semordnilaps {
Document d$
Line 2,070 ⟶ 2,156:
}
semordnilaps
</syntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll">
Line 2,081 ⟶ 2,167:
</pre >
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
result = DeleteDuplicates[ Select[data, MemberQ[data, StringReverse[#]]
&& # =!= StringReverse[#] &], (# ===StringReverse[#2]) &];
Print[Length[result], Take[result, 5]]</
{{out}}
<pre>158 {able,abut,ac,ah,al}</pre>
Line 2,091 ⟶ 2,177:
=={{header|Nanoquery}}==
{{trans|Java}}
<
def reverse_str(string)
Line 2,119 ⟶ 2,205:
end
println "\nSemordnilap pairs found: " + count</
{{out}}
<pre>ca ac
Line 2,131 ⟶ 2,217:
=={{header|NetRexx}}==
{{Trans|REXX}}
<
options replace format comments java crossref symbols nobinary
Line 2,160 ⟶ 2,246:
Say pi 'words in' fid 'have a palindrome' /* total number found */
return
</syntaxhighlight>
{{out}}
<pre>
Line 2,172 ⟶ 2,258:
=={{header|NewLisp}}==
<syntaxhighlight lang="newlisp">
;;; Get the words as a list, splitting at newline
(setq data
Line 2,199 ⟶ 2,285:
(dolist (x res)
(if (> (length x) 4) (println x " -- " (get-reverse x))))
</syntaxhighlight>
{{out}}
<pre>
Line 2,212 ⟶ 2,298:
=={{header|Nim}}==
<
proc reversed(s: string): string =
Line 2,227 ⟶ 2,313:
echo "Total number of semordnilaps: ", pairs.len
pairs = pairs.sortedByIt(it[0].len)
echo pairs[^5..^1]</
{{out}}
Line 2,234 ⟶ 2,320:
=={{header|OCaml}}==
<
let str_rev s =
Line 2,267 ⟶ 2,353:
let (word, rev) = List.nth pairs (Random.int len) in
Printf.printf " %s %s\n" word rev
done</
{{out}}
Line 2,280 ⟶ 2,366:
=={{header|Octave}}==
<
a = intersect(a, cellfun(@fliplr, a, "UniformOutput", false));
a = a(arrayfun(@(i) ismember(fliplr(a{i}), a(i+1:length(a))), 1:length(a)));
length(a)
arrayfun(@(i) printf("%s %s\n", a{i}, fliplr(a{i})), 1:5)</
'''Output:'''
Line 2,298 ⟶ 2,384:
=={{header|Oforth}}==
<
| w wr wrds |
ListBuffer new ->wrds
Line 2,305 ⟶ 2,391:
wrds include(w reverse dup ->wr) ifTrue: [ [wr, w] over add ]
w wr < ifTrue: [ wrds add(w) ]
] ;</
{{out}}
Line 2,315 ⟶ 2,401:
=={{header|Perl}}==
<
chomp;
my $r = reverse;
Line 2,321 ⟶ 2,407:
}
print "$c\n"</
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">words</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">unix_dict</span><span style="color: #0000FF;">(),</span> <span style="color: #000000;">semordnilap</span><span style="color: #0000FF;">={}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">word</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">rfind</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">),</span><span style="color: #000000;">words</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">semordnilap</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">semordnilap</span><span style="color: #0000FF;">,</span><span style="color: #000000;">word</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d semordnilap found, the first five are:\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">semordnilap</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s - %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">semordnilap</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">semordnilap</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
158 semordnilap found, the first five are:
ca - ac
dab - bad
diva - avid
dna - and
drab - bard
</pre>
=={{header|Phixmonti}}==
<syntaxhighlight lang="Phixmonti">include ..\Utilitys.pmt
( ) ( )
"unixdict.txt" "r" fopen var f
true while
f fgets
dup -1 == if
drop
f fclose
false
else
-1 del
0 put
true
endif
endwhile
len while
len 1 > if
pop swap reverse find dup
if
extract rot swap 0 put swap
else
drop
endif
true
else
drop false
endif
endwhile
( 50 54 ) for get dup reverse print " -> " print ? endfor nl
len print " pairs" ?</syntaxhighlight>
{{out}}
<pre>dew -> wed
dial -> laid
dim -> mid
dine -> enid
dog -> god
158 pairs
=== Press any key to exit ===</pre>
=={{header|PHP}}==
{{trans|Raku}}
<
// Read dictionary into array
$dictionary = array_fill_keys(file(
Line 2,370 ⟶ 2,497:
// array_rand() returns keys, not values
foreach (array_rand($words, 5) as $word)
echo "$word $words[$word]\n";</
{{out}}
<pre>158
Line 2,380 ⟶ 2,507:
=={{header|PicoLisp}}==
<
(mapcon
'((Lst)
Line 2,386 ⟶ 2,513:
(cons (pack (car Lst))) ) )
(make (in "unixdict.txt" (while (line) (link @)))) )
(println (length Semordnilap) (head 5 Semordnilap)) )</
{{out}}
<pre>158 ("able" "abut" "ac" "ah" "al")</pre>
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
find: procedure options (main); /* 20/1/2013 */
declare word character (20) varying controlled;
Line 2,433 ⟶ 2,560:
end;
end find;
</syntaxhighlight>
<pre>
There are 158 pairs.
Line 2,447 ⟶ 2,574:
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function Reverse-String ([string]$String)
{
Line 2,483 ⟶ 2,610:
"`nSemordnilap count: {0}" -f ($semordnilap.GetEnumerator() | Measure-Object).Count
</syntaxhighlight>
{{Out}}
Line 2,501 ⟶ 2,628:
Semordnilap count: 158
</pre>
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">If OpenConsole("")=0 : End 1 : EndIf
If ReadFile(0,"./Data/unixdict.txt")=0 : End 2 : EndIf
NewList dict$()
While Eof(0)=0 : AddElement(dict$()) : dict$()=Trim(ReadString(0)) : Wend : CloseFile(0)
While FirstElement(dict$())
buf$=dict$() : DeleteElement(dict$())
If buf$="" : Continue : EndIf
xbuf$=ReverseString(buf$)
ForEach dict$()
If xbuf$=dict$()
res$+buf$+" / "+xbuf$+#LF$
Break
EndIf
Next
Wend
PrintN("Semordnilap pairs found: "+Str(CountString(res$,#LF$)))
For k=1 To 5
If k=1 : PrintN(~"\nFirst 5 pairs: "+StringField(res$,k,#LF$)) : Continue : EndIf
PrintN(Space(15)+StringField(res$,k,#LF$))
Next
Input()</syntaxhighlight>
{{out}}
<pre>Semordnilap pairs found: 158
First 5 pairs: able / elba
abut / tuba
ac / ca
ah / ha
al / la</pre>
=={{header|Python}}==
===Idiomatic===
<
wordset = set(f.read().strip().split())
>>> revlist = (''.join(word[::-1]) for word in wordset)
>>> pairs = set((
if
>>> len(pairs)
158
>>> sorted(pairs, key=lambda p: (len(p[0]), p))[-5:]
[('damon', 'nomad'), ('lager', 'regal'), ('leper', 'repel'), ('lever', 'revel'), ('kramer', 'remark')]
>>> </
===As a fold, using reduce===
{{Works with|Python|3.7}}
<
from functools import (reduce)
Line 2,654 ⟶ 2,790:
if __name__ == '__main__':
main()</
{{Out}}
<pre>Dictionary words paired by equivalence under reversal:
Line 2,670 ⟶ 2,806:
Requires the <code>requests</code> library.
<
import random
import requests
Line 2,710 ⟶ 2,846:
print(
f'found {len(semordnilaps)} semordnilap
* ['%s %s' % p for p in example_pairs]+['...'],
sep='\n'
Line 2,720 ⟶ 2,856:
if __name__ == '__main__':
main(*sys.argv[1:])
</syntaxhighlight>
{{Out}}
<pre>
found 158 semordnilap
mug gum
revel lever
Line 2,732 ⟶ 2,868:
...
</pre>
=={{header|Quackery}}==
<syntaxhighlight lang="quackery"> []
$ "rosetta/unixdict.txt" sharefile drop
nest$
[ behead reverse swap
2dup find over found iff
[ dip [ nested join ] ]
else nip
dup [] = until ]
drop
say "Number of semordnilaps: "
dup size echo cr
sortwith [ size swap size > ]
5 split drop
say "Five longest: "
witheach
[ dup echo$ say "<->"
reverse echo$ sp ]</syntaxhighlight>
{{out}}
<pre>Number of semordnilaps: 158
Five longest: remark<->kramer nomad<->damon regal<->lager repel<->leper revel<->lever
</pre>
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
(define seen (make-hash))
Line 2,749 ⟶ 2,912:
(for ([s (take (sort semordnilaps > #:key (compose1 string-length car)) 5)])
(apply printf " ~s ~s\n" s))
</syntaxhighlight>
{{out}}
Line 2,765 ⟶ 2,928:
(formerly Perl 6)
{{works with|rakudo|2015-10-26}}
<syntaxhighlight lang="raku"
my @sems = gather for $words.flat -> $word {
Line 2,772 ⟶ 2,935:
}
say $_ ~ ' ' ~ $_.flip for @sems.pick(5);</
{{out}}
<pre>abut tuba
Line 2,782 ⟶ 2,945:
=={{header|REXX}}==
===version 1===
<
* 07.09.2012 Walter Pachl
**********************************************************************/
Line 2,800 ⟶ 2,963:
End
End
Say pi 'words in' fid 'have a palindrome' /* total number found */</
{{out}}
<pre>
Line 2,813 ⟶ 2,976:
===version 2===
This REXX version makes use of sparse (stemmed) arrays.
The dictionary file wasn't assumed to be in any particular case (upper/lower/mixed).
For instance, '''DNA''' <big> & </big> '''and''' would be considered semordnilaps, even though their ''case'' is different.
The UNIXDICT dictionary specified to be used ''is'' all lowercase, however, but the REXX program assumes that the
<br>words may be in any ''case'' (lowercase/uppercase/mixedcased).
Any blank lines or ''duplicate words'' in the dictionary are ignored (as duplicate words wouldn't make them unique).
Any leading, trailing, or imbedded blanks are also ignored (as well as tab characters or other whitespace).
The semordnilap word pairs are shown with a comma delimiter in case there are phrases (words with imbedded
<br>blanks like ''Sing Sing'').
The (first five) semordnilap pairs are shown as they are specified/defined (respective to case) in the dictionary.
<syntaxhighlight lang="rexx">/*REXX program finds N semordnilap pairs using a specified dictionary (UNIXDICT.TXT).*/
parse arg n iFID
if
if iFID=='' | iFID==","
#= 0 /*number of semordnilaps (so far). */
@.= /*caseless non─duplicated dict. words. */
do while lines(iFID)\==0; _= linein(iFID); u= space(_, 0); upper u /*get a word.*/
if length(u)<2 | @.u\=='' then iterate /*word can't be a unique semordnilap. */
r= reverse(u) /*obtain reverse of the dictionary word*/
if @.r\=='' then do; #= # + 1 /*found a semordnilap word; bump count.*/
if #<=n then say right(@.r, max(32, length(@.r) ) )',' u
end
@.u= _ /*define reverse of the dictionary word*/
end /*while*/ /*stick a fork in it, we're all done. */
say
say "There're "
{{out|output|text= when using the default inputs:}}
<pre>
ac, ca
bad, dab
avid, diva
and, dna
bard, drab
There're 158 unique
</pre>
=={{header|Ring}}==
<
# Project : Semordnilap
Line 2,875 ⟶ 3,047:
nr = find(aList,bString)
return nr
</syntaxhighlight>
{{out}}
<pre>
Line 2,888 ⟶ 3,060:
=={{header|Ruby}}==
Note: An alternative (old fashioned) method of solving this task (not using a Set as done by other solutions) is to produce 2 sorted files and walk through them. This can be done entirly on disk if required, when done in memory it is faster than a set for large samples.--[[User:Nigel Galloway|Nigel Galloway]] 11:12, 17 September 2012 (UTC)
<
i = 0
res = dict.collect(&:reverse).sort.select do |z|
Line 2,895 ⟶ 3,067:
end
puts "There are #{res.length} semordnilaps, of which the following are 5:"
res.take(5).each {|z| puts "#{z} #{z.reverse}"}</
{{out}}
<pre>
Line 2,907 ⟶ 3,079:
Another way
<
.group_by{|x| [x.strip!, x.reverse].min}
.values
.select{|v| v.size==2}
puts "There are #{words.size} semordnilaps, of which the following are 5:"
words.take(5).each {|a,b| puts "#{a} #{b}"}</
output is the same above.
=={{header|Rust}}==
{{trans|Java}}
<
use std::fs::File;
use std::io::{self, BufRead};
Line 2,948 ⟶ 3,120:
Err(error) => eprintln!("{}", error),
}
}</
{{out}}
Line 2,960 ⟶ 3,132:
Semordnilap pairs found: 158
</pre>
===A Shortened Version===
<syntaxhighlight lang="rust">use std::{collections::HashSet, fs};
fn reverse(x: &str) -> String {
x.chars().rev().collect::<String>()
}
fn main() {
let content = fs::read_to_string("unixdict.txt").expect("No file found!");
let work: HashSet<&str> = content.lines().collect();
let mut candidats: Vec<&str> = work.clone().into_iter().collect();
candidats.retain(|&x| work.contains(&reverse(x).as_str()) && x < reverse(x).as_str());
println!("Numbers of pairs found: {}", candidats.len());
for ind in 0..5 {
println!("{}, {}", candidats[ind], reverse(candidats[ind]));
}
}</syntaxhighlight>
{{out}}
<pre>Numbers of pairs found: 158
mn, nm
map, pam
saw, was
deep, peed
door, rood</pre>
=={{header|Scala}}==
<syntaxhighlight lang="scala">val wordsAll =
scala.io.Source.
fromURL("http://wiki.puzzlers.org/pub/wordlists/unixdict.txt").
getLines().map(_.toLowerCase).toIndexedSeq
/**
Line 2,969 ⟶ 3,171:
* words are different.
*/
def semordnilap( words:
zipWithIndex. // index will be needed to eliminate duplicate
filter {
case (w,i) =>
val j = words.indexOf(w.reverse) // eg. (able,62) and (elba,7519)
i < j && w != w.reverse // save the matches which are not palindromes
}.
map {
case (w,_) => (w,w.reverse) // drop the index
}
}
Line 2,987 ⟶ 3,188:
{
println( s"${ss.size
println( ss.take(5).mkString( "\n" ) )
}</
{{out}}
<pre>158 matches, including:
Line 3,001 ⟶ 3,202:
=={{header|Seed7}}==
Note that the Seed7 program downloads unixdict.txt from the net.
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "gethttp.s7i";
const proc: main is func
Line 3,023 ⟶ 3,214:
var integer: count is 0;
begin
wordList := split(lower(getHttp("
for word range wordList do
drow := reverse(word);
Line 3,037 ⟶ 3,228:
writeln;
writeln("Semordnilap pairs: " <& count);
end func;</
{{out}}
Line 3,052 ⟶ 3,243:
=={{header|Sidef}}==
{{trans|Perl}}
<
var seen = Hash()
Line 3,062 ⟶ 3,253:
}
say c</
{{out}}
<pre>
Line 3,072 ⟶ 3,263:
drab bard
158
</pre>
=={{header|SNOBOL4}}==
{{works with|SNOBOL4, SPITBOL for Linux}}
<syntaxhighlight lang="snobol4">
* Program: semordnilap.sbl
* To run: sbl semordnilap.sbl < unixdict.txt
* Description: A semordnilap is a word (or phrase) that spells
* a different word (or phrase) backward. "Semordnilap"
* is a word that itself is a semordnilap.
* Example: lager and regal
* Reads file unixdict.txt
* Comment: Tested using the Spitbol for Linux version of SNOBOL4
output = "Some Semordnilap Pairs from File unixdict.txt"
atable = table(25200,,-1)
ntable = table(25200,,-2)
* Read dictionary file into memory
in1
word = input :f(p1)
count = count + 1
atable[word] = word
ntable[count] = word
:(in1)
* Process dictionary to find unique semordnilaps
p1
i = lt(i,count) i + 1 :f(p2)
newword = atable[reverse(ntable[i])]
leq(newword,-1) :s(p1)
ident(ntable[i],newword) :s(p1)
output = lt(outcount,5) ntable[i] ', ' newword
atable[ntable[i]] = atable[newword] = -1
outcount = outcount + 1
:(p1)
p2
output = 'The number of semordnilap pairs is: ' outcount
END
</syntaxhighlight>
{{out}}
<pre>
Some Semordnilap Pairs from File unixdict.txt
able, elba
abut, tuba
ac, ca
ah, ha
al, la
The number of semordnilap pairs is: 158
</pre>
=={{header|Stata}}==
<
import delimited http://www.puzzlers.org/pub/wordlists/unixdict.txt, clear
save temp, replace
Line 3,093 ⟶ 3,333:
| nit tin |
| ku uk |
+-------------+</
=={{header|SuperCollider }}==
Submitted to Rosetta Code 2024-06-07 by: MusicCoder.
<syntaxhighlight lang="SuperCollider">
// ==========================================================================
// START-SuperCollider solution to Rosetta Code TASK: Semordnilap ## BY: MusicCoder : 2024-06-07 ##
// ==========================================================================
(
/*
https://rosettacode.org/wiki/Semordnilap
A semordnilap is a word (or phrase) that spells a **different word** (or phrase) backward.
"Semordnilap" is a word that itself is a semordnilap, i.e. palindromes. Example: lager and regal
This task does not consider semordnilap phrases, only single words.
Using only words from this list: unixdict.txt,
report the total number of unique semordnilap pairs, and print 5 examples.
Two matching semordnilaps, such as lager and regal, should be counted as ***one unique pair***.
*/
var text, words, revs, candidates, pairs, selection;
// open file and read all contents into a single string variable called text
File.use("~/rosetta/data/unixdict.txt".standardizePath, "r", { |f| text = f.readAllString });
// to get words - split on new-line, to get distinct convert to SET
words = text.split(Char.nl).as(Set);
// reverse order of all characters then split & convert as above
revs = text.reverse.split(Char.nl).as(Set);
// get the intersection of the two sets: forward and reversed words
candidates = (words & revs).as(Array);
// use a list comprehension to build the pairs AND to drop any palindromes & revs
pairs = all {: [word, rev], word <- candidates, var rev = word.reverse, word < rev };
"There are % semordnilas in unixdict.txt\n".postf(pairs.size);
"For example those, with more than 3 characters:".postln;
// SELECT only those pairs where the word length is >= 4
// SCRAMBLE the resulting array and KEEP only 5 pairs
selection = pairs.select { |each| each[0].size >= 4 }.scramble.keep(5);
// PRINT each example on a new line
selection.do { |each| each.postln; };"\n";
)
// ==========================================================================
// **END-SuperCollider solution to Rosetta Code TASK: Semordnilap ## BY: MusicCoder : 2024-06-07 ##
// ==========================================================================
</syntaxhighlight>
{{out}}
<pre>
There are 158 semordnilas in unixdict.txt
For example those, with more than 3 characters:
[ gnaw, wang ]
[ part, trap ]
[ hoop, pooh ]
[ leper, repel ]
[ aryl, lyra ]
</pre>
=={{header|Swift}}==
<
fatalError()
}
Line 3,134 ⟶ 3,402:
print("Found \(pairs.count) pairs")
print("Five examples: \(pairs.prefix(5))")</
{{out}}
Line 3,142 ⟶ 3,410:
=={{header|Tcl}}==
<
package require http
Line 3,171 ⟶ 3,439:
puts "Example: $pair"
if {[incr i]>=5} break
}</
{{out}}
<pre>
Line 3,180 ⟶ 3,448:
Example: eros/sore
Example: bard/drab
</pre>
=={{header|Transd}}==
<syntaxhighlight lang="scheme">#lang transd
MainModule: {
_start: (λ (with fs FileStream()
(open-r fs "/mnt/vault/tmp/unixdict.txt") )
(with v ( -|
(read-text fs)
(split)
(group-by (λ s String() -> String()
(ret (min s (reverse (cp s))))))
(values)
(filter where: (λ v Vector<String>() (ret (== (size v) 2))))
(shuffle))
(lout "Total number of semordnilaps: " (size v))
(lout "Random five: " Range(in: v 0 5))))
)
}</syntaxhighlight>
{{out}}
<pre>
Total number of semordnilaps: 158
Random five: [[deer, reed], [nip, pin], [eire, erie], [am, ma], [gem, meg]]
</pre>
=={{header|TUSCRIPT}}==
<
$$ MODE TUSCRIPT,{}
requestdata = REQUEST ("http://www.puzzlers.org/pub/wordlists/unixdict.txt")
Line 3,207 ⟶ 3,500:
ENDLOOP
ENDCOMPILE
</syntaxhighlight>
{{out}}
<pre>
Line 3,217 ⟶ 3,510:
4. ah'ha
5. al'la
</pre>
=={{header|Uiua}}==
For each word check its reverse is in the array, and that it's greater. This removes palindromes and also keeps only first of each pair.
<syntaxhighlight lang="Uiua">
&p &pf "Count: " ⧻.▽≡(×>⇌.⟜∊⇌)⟜¤. ⊜□ ≠@\n. &fras "unixdict.txt"
</syntaxhighlight>
{{out}}
<pre>
Count: 158
{"able" "abut" "ac" "ah" "al" "am" "amos" "and" "ape" "aps" "are"
...
"pot" "pow" "pus" "rat" "raw" "rot" "saw" "suez" "tort" "tv" "way"}
</pre>
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInFile = objFSO.OpenTextFile(objFSO.GetParentFolderName(WScript.ScriptFullName) &_
Line 3,257 ⟶ 3,564:
Set objUnixDict = Nothing
Set objSemordnilap = Nothing
</syntaxhighlight>
{{out}}
Line 3,270 ⟶ 3,577:
=={{header|Wren}}==
<
var dict = File.read("unixdict.txt").split("\n")
Line 3,290 ⟶ 3,597:
for (i in 0..4) System.print(" %(pairs[i][0]), %(pairs[i][1])")
System.print("\nand the last five are:")
for (i in -5..-1) System.print(" %(pairs[i][0]), %(pairs[i][1])")</
{{out}}
Line 3,312 ⟶ 3,619:
=={{header|XPL0}}==
<
string 0; \use zero-terminated strings
def LF=$0A, CR=$0D, EOF=$1A;
Line 3,371 ⟶ 3,678:
];
IntOut(0, Count); CrLf(0);
]</
{{out}}
Line 3,382 ⟶ 3,689:
158
</pre>
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">dim norm$(27000), result$(270, 2)
print "Start reading unixdict.txt"
open "i:\unixdict.txt" for reading as #1
while not(eof(#1)) // read to end of file
line input #1 in_str$ // get line = word
in_str$ = trim$(in_str$) // we don//t want spaces
if len(in_str$) > 1 then // if length > 1 then reverse$
rev$ = reverse$(in_str$)
if in_str$ <> rev$ then // if in_str is not a palingdrome
count = count + 1 // increase counter
norm$(count) = in_str$ // store in the array
big$ = big$ + rev$ + " " // create big string with reverse$d words
fi
fi
wend
close #1
print " ... Done"
print
print "Start looking for semordnilap"
for i = 1 to count
for j = 1 to amount // check to avoid the double
if result$(j, 2) = norm$(i) continue
next j
j = instr(big$, " " + norm$(i) + " ")
if j <> 0 then // found one
amount = amount + 1 // increase counter
result$(amount, 1) = norm$(i) // store normal word
result$(amount, 2) = reverse$(norm$(i)) // store reverse$ word
fi
next i
print
print "Found", amount, " unique semordnilap pairs"
print
print "Display 5 semordnilap pairs"
print
count = 0
for i = 1 to amount
if len(result$(i, 1)) >= 5 then
count = count + 1
print result$(i, 1), chr$(9), result$(i, 2)
if count >= 5 break
fi
next i
end
sub reverse$(norm$)
local rev$, i, l
l = len(norm$) - 1
rev$ = norm$
for i = 0 to l
mid$(rev$, l - i, 1) = mid$(norm$, i, 1)
next i
return rev$
end sub</syntaxhighlight>
{{out}}
<pre>
Start reading unixdict.txt
... Done
Start looking for semordnilap
Found70 unique semordnilap pairs
Display 5 semordnilap pairs
diesel seidel
dirge ridge
gamma magma
groan organ
latus talus
---Program done, press RETURN---</pre>
=={{header|zkl}}==
<
File("dict.txt").howza(11).pump(Dictionary().howza(8).add.fp1(True));
ss:=words.pump(List, // push stripped unixdict words through some functions
Line 3,392 ⟶ 3,780:
ss.len().println(); //--> 158
ss.shuffle()[0,5].println();</
{{out}}
<pre>
Line 3,400 ⟶ 3,788:
{{omit from|6502 Assembly|unixdict.txt is much larger than the CPU's address space.}}
{{omit from|8080 Assembly|See 6502 Assembly.}}
{{omit from|Brlcad}}
{{omit from|GUISS}}
Line 3,405 ⟶ 3,795:
{{omit from|Openscad}}
{{omit from|TPP}}
{{omit from|Z80 Assembly|See 6502 Assembly.}}
{{omit from|ZX Spectrum Basic}}
|