Data update
This commit is contained in:
parent
29a5eea0d4
commit
5c1bb7bfa9
2011 changed files with 35081 additions and 3229 deletions
108
Task/Wordiff/Jq/wordiff.jq
Normal file
108
Task/Wordiff/Jq/wordiff.jq
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
include "MRG32k3a" {search: "."}; # see comment above
|
||||
|
||||
### Generic functions
|
||||
|
||||
# Determine if stream is non-decreasing
|
||||
def is_sorted(stream):
|
||||
first(foreach stream as $s ( null;
|
||||
if . == null or $s >= .[0] then [$s]
|
||||
else 0
|
||||
end;
|
||||
select(. == 0) ) )
|
||||
// 1
|
||||
| . == 1;
|
||||
|
||||
# Write to stderr
|
||||
def inform(msg):
|
||||
. as $in
|
||||
| ("\(msg)\n" | stderr)
|
||||
| $in;
|
||||
|
||||
# q means quit
|
||||
def read($prompt; $regex):
|
||||
def r:
|
||||
($prompt | stderr | empty),
|
||||
(try ((input
|
||||
| if . == "q" then halt
|
||||
else select(test($regex))
|
||||
end) // r)
|
||||
catch if . == "break" then halt else r end );
|
||||
r;
|
||||
|
||||
# Returns levenshteinDistance(s1; $s2) <= $max
|
||||
# A recursive algorithm is good enough if $max is small
|
||||
def levenshteinDistance($s1; $s2; $max):
|
||||
def lev:
|
||||
. as [$s1, $s2, $max]
|
||||
| if ($s1|length) == 0 then ($s2|length) <= $max
|
||||
elif ($s2|length) == 0 then ($s1|length) <= $max
|
||||
elif $s1[:1] == $s2[:1]
|
||||
then [$s1[1:], $s2[1:], $max] | lev
|
||||
else ($s1|length) <= $max
|
||||
or ($s2|length) <= $max
|
||||
or ([$s1[1:], $s2, $max-1] | lev)
|
||||
or ([$s1, $s2[1:], $max-1] | lev)
|
||||
or ([$s1[1:], $s2[1:], $max-1] | lev)
|
||||
end ;
|
||||
[$s1, $s2, $max] | lev;
|
||||
|
||||
##### The Wordiff Game
|
||||
|
||||
# Output: the sorted list of words
|
||||
# The sort is skipped if we can readily determine the list is already sorted
|
||||
def words:
|
||||
[$dict | splits(" *\n *")]
|
||||
| if is_sorted(.[]) then .
|
||||
else sort
|
||||
end;
|
||||
|
||||
def player1: read("Player 1, please enter your name : "; ".");
|
||||
def player2: read("Player 2, please enter your name : "; ".");
|
||||
|
||||
def round:
|
||||
.words as $words
|
||||
| read("\(.player), enter your word: "; ".") as $word
|
||||
| ($word|length) as $len
|
||||
| .ok = false
|
||||
| if $len < 3
|
||||
then inform("Words must be at least three letters long.")
|
||||
elif $word == .prevWord
|
||||
then inform("You must change the previous word.")
|
||||
elif .used[$word]
|
||||
then inform("The word \"\($word)\" has been used before.")
|
||||
elif # not in dictionary
|
||||
# if $words is not sorted: ($word | IN($words[]) | not)
|
||||
# binary search:
|
||||
($words | bsearch($word) < 0)
|
||||
then inform("Not in dictionary.")
|
||||
|
||||
elif levenshteinDistance($word; .prevWord; 1)
|
||||
#### Good to go
|
||||
then .ok = true
|
||||
| .prevLen = ($word|length)
|
||||
| .prevWord = $word
|
||||
| .used[$word] = true
|
||||
| .player = (if .player == .player1 then .player2 else .player1 end)
|
||||
else inform("Sorry. Only one addition, deletion or alteration is allowed.")
|
||||
end
|
||||
| if (.ok|not) then inform("Please retry. The current word is: \(.prevWord)") end
|
||||
| round ;
|
||||
|
||||
def play:
|
||||
player1 as $player1
|
||||
| { player1: $player1,
|
||||
player2: ( player2 | if . == $player1 then . + "2" else . end)
|
||||
}
|
||||
| inform("Reading and perhaps sorting the list of words takes a few seconds... ")
|
||||
| inform("Meanwhile note that you can quit by entering q at a prompt.")
|
||||
| .words = words
|
||||
# Avoid storing the subset of words needed to make a random selection:
|
||||
| (.words | map(select(length | IN(3,4))) | .[length | prn(1)[]]) as $firstWord
|
||||
| .prevLen = ($firstWord|length)
|
||||
| .prevWord = $firstWord
|
||||
| .used = {($firstWord): true} # a JSON object for efficiency
|
||||
| .player = .player1
|
||||
| "\nThe first word is: \($firstWord)",
|
||||
round;
|
||||
|
||||
play
|
||||
Loading…
Add table
Add a link
Reference in a new issue