State name puzzle: Difference between revisions
m (heading fix) |
m (→{{header|Wren}}: Minor tidy) |
||
(107 intermediate revisions by 45 users not shown) | |||
Line 1: | Line 1: | ||
{{ |
{{task|Puzzles}} |
||
'''Background''' |
'''Background''' |
||
This task is inspired by [http://drdobbs.com/windows/198701685 Mark Nelson's DDJ Column "Wordplay"] and one of the weekly puzzle challenges from Will Shortz on NPR Weekend Edition [http://www.npr.org/templates/story/story.php?storyId=9264290] and originally attributed to David Edelheit. |
This task is inspired by [http://drdobbs.com/windows/198701685 Mark Nelson's DDJ Column "Wordplay"] and one of the weekly puzzle challenges from Will Shortz on NPR Weekend Edition [http://www.npr.org/templates/story/story.php?storyId=9264290] and originally attributed to David Edelheit. |
||
The challenge was to take the names of two U.S. States, mix them all together, then rearrange the letters to form the names of two |
The challenge was to take the names of two U.S. States, mix them all together, then rearrange the letters to form the names of two ''different'' U.S. States (so that all four state names differ from one another). |
||
What states are these? |
|||
The problem was reissued on [https://tapestry.tucson.az.us/twiki/bin/view/Main/StateNamesPuzzle the Unicon Discussion Web] which includes several solutions with analysis. Several techniques may be helpful and you may wish to refer to [[wp:Goedel_numbering|Goedel numbering]], [[wp:Equivalence_relation|Equivalence relations]], and [[wp:Equivalence_classes|Equivalence classes]]. The basic merits of these were discussed in the Unicon Discussion Web. |
|||
The problem was reissued on [https://tapestry.tucson.az.us/twiki/bin/view/Main/StateNamesPuzzle the Unicon Discussion Web] which includes several solutions with analysis. Several techniques may be helpful and you may wish to refer to [[wp:Goedel_numbering|Gödel numbering]], [[wp:Equivalence_relation|equivalence relations]], and [[wp:Equivalence_classes|equivalence classes]]. The basic merits of these were discussed in the Unicon Discussion Web. |
|||
A second challenge in the form of a set of fictitious new states was also presented. |
A second challenge in the form of a set of fictitious new states was also presented. |
||
'''Task''' |
|||
;Task: |
|||
Write a program to solve the challenge using both the original list of states and the fictitous list. |
|||
Write a program to solve the challenge using both the original list of states and the fictitious list. |
|||
Caveats: |
|||
;Caveats: |
|||
* case and spacing isn't significant - just letters (harmonize case) |
|||
* case and spacing aren't significant - just letters (harmonize case) |
|||
* don't expect the names to be in any order |
|||
* don't |
* don't expect the names to be in any order - such as being sorted |
||
* don't rely on names to be unique (eliminate duplicates - meaning if Iowa appears twice you can only use it once) |
|||
<br />Comma separated list of state names used in the original puzzle:<pre> "Alabama", "Alaska", "Arizona", "Arkansas", |
|||
Comma separated list of state names used in the original puzzle: |
|||
<pre> |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", "Delaware", |
|||
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois", |
|||
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
</pre> |
|||
Comma separated list of additional fictitious state names to be added to the original (Includes a duplicate): |
|||
<pre> |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory" |
|||
</pre> |
|||
{{Template:Strings}} |
|||
<br><br> |
|||
=={{header|11l}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="11l">V states = [‘Alabama’, ‘Alaska’, ‘Arizona’, ‘Arkansas’, |
|||
‘California’, ‘Colorado’, ‘Connecticut’, ‘Delaware’, ‘Florida’, |
|||
‘Georgia’, ‘Hawaii’, ‘Idaho’, ‘Illinois’, ‘Indiana’, ‘Iowa’, ‘Kansas’, |
|||
‘Kentucky’, ‘Louisiana’, ‘Maine’, ‘Maryland’, ‘Massachusetts’, |
|||
‘Michigan’, ‘Minnesota’, ‘Mississippi’, ‘Missouri’, ‘Montana’, |
|||
‘Nebraska’, ‘Nevada’, ‘New Hampshire’, ‘New Jersey’, ‘New Mexico’, |
|||
‘New York’, ‘North Carolina’, ‘North Dakota’, ‘Ohio’, ‘Oklahoma’, |
|||
‘Oregon’, ‘Pennsylvania’, ‘Rhode Island’, ‘South Carolina’, |
|||
‘South Dakota’, ‘Tennessee’, ‘Texas’, ‘Utah’, ‘Vermont’, ‘Virginia’, |
|||
‘Washington’, ‘West Virginia’, ‘Wisconsin’, ‘Wyoming’] |
|||
states = sorted(states) |
|||
DefaultDict[String, [String]] smap |
|||
L(s1) states[0 .< (len)-1] |
|||
V i = L.index |
|||
L(s2) states[i+1..] |
|||
smap[sorted(s1‘’s2)].append(s1‘ + ’s2) |
|||
L(pairs) sorted(smap.values()) |
|||
I pairs.len > 1 |
|||
print(pairs.join(‘ = ’))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
North Carolina + South Dakota = North Dakota + South Carolina |
|||
</pre> |
|||
=={{header|AppleScript}}== |
|||
<syntaxhighlight lang="applescript">use AppleScript version "2.3.1" -- Mac OS X 10.9 (Mavericks) or later. |
|||
use sorter : script ¬ |
|||
"Custom Iterative Ternary Merge Sort" -- <www.macscripter.net/t/timsort-and-nigsort/71383/3> |
|||
on stateNamePuzzle() |
|||
script o |
|||
property stateNames : {"Alabama", "Alaska", "Arizona", "Arkansas", ¬ |
|||
"California", "Colorado", "Connecticut", "Delaware", ¬ |
|||
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois", ¬ |
|||
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", ¬ |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", ¬ |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", ¬ |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", ¬ |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", ¬ |
|||
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", ¬ |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", ¬ |
|||
"Utah", "Vermont", "Virginia", ¬ |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming", ¬ |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"} |
|||
property workList : {} |
|||
-- Custom comparison handler for the sort. |
|||
on isGreater(a, b) |
|||
return (beginning of a > beginning of b) |
|||
end isGreater |
|||
end script |
|||
ignoring case |
|||
-- Remove duplicates. |
|||
repeat with i from 1 to (count o's stateNames) |
|||
set thisName to o's stateNames's item i |
|||
if ({thisName} is not in o's workList) then set end of o's workList to thisName |
|||
end repeat |
|||
set o's stateNames to o's workList |
|||
-- Build a list of lists containing unique pairs of names preceded by |
|||
-- text composed of their combined and sorted visible characters. |
|||
set o's workList to {} |
|||
set stateCount to (count o's stateNames) |
|||
repeat with i from 1 to (stateCount - 1) |
|||
set name1 to o's stateNames's item i |
|||
repeat with j from (i + 1) to stateCount |
|||
set name2 to o's stateNames's item j |
|||
set chrs to (name1 & name2)'s characters |
|||
tell sorter to sort(chrs, 1, -1, {}) |
|||
set end of o's workList to {join(chrs, "")'s word 1, {name1, name2}} |
|||
end repeat |
|||
end repeat |
|||
-- Sort the lists on the character strings |
|||
set pairCount to (count o's workList) |
|||
tell sorter to sort(o's workList, 1, pairCount, {comparer:o}) |
|||
-- Look for groups of equal character strings and match |
|||
-- associated name pairs not containing the same name(s). |
|||
set output to {} |
|||
set l to 1 |
|||
repeat while (l < pairCount) |
|||
set chrs to beginning of o's workList's item l |
|||
set r to l |
|||
repeat while ((r < pairCount) and (beginning of o's workList's item (r + 1) = chrs)) |
|||
set r to r + 1 |
|||
end repeat |
|||
if (r > l) then |
|||
repeat with i from l to (r - 1) |
|||
set {name1, name2} to end of o's workList's item i |
|||
set text1 to join(result, " and ") & " --> " |
|||
repeat with j from (i + 1) to r |
|||
set pair2 to end of o's workList's item j |
|||
if (not (({name1} is in pair2) or ({name2} is in pair2))) then |
|||
set end of output to text1 & join(pair2, " and ") |
|||
end if |
|||
end repeat |
|||
end repeat |
|||
end if |
|||
set l to r + 1 |
|||
end repeat |
|||
end ignoring |
|||
return join(output, linefeed) |
|||
end stateNamePuzzle |
|||
on join(lst, delim) |
|||
set astid to AppleScript's text item delimiters |
|||
set AppleScript's text item delimiters to delim |
|||
set txt to lst as text |
|||
set AppleScript's text item delimiters to astid |
|||
return txt |
|||
end join |
|||
stateNamePuzzle()</syntaxhighlight> |
|||
{{output}} |
|||
<syntaxhighlight lang="applescript">"North Carolina and South Dakota --> North Dakota and South Carolina |
|||
New York and New Kory --> Wen Kory and York New |
|||
New York and New Kory --> Wen Kory and Kory New |
|||
New York and New Kory --> York New and Kory New |
|||
New York and Wen Kory --> New Kory and York New |
|||
New York and Wen Kory --> New Kory and Kory New |
|||
New York and Wen Kory --> York New and Kory New |
|||
New York and York New --> New Kory and Wen Kory |
|||
New York and York New --> New Kory and Kory New |
|||
New York and York New --> Wen Kory and Kory New |
|||
New York and Kory New --> New Kory and Wen Kory |
|||
New York and Kory New --> New Kory and York New |
|||
New York and Kory New --> Wen Kory and York New |
|||
New Kory and Wen Kory --> York New and Kory New |
|||
New Kory and York New --> Wen Kory and Kory New |
|||
New Kory and Kory New --> Wen Kory and York New" |
|||
</syntaxhighlight> |
|||
=={{header|Bracmat}}== |
|||
<syntaxhighlight lang="bracmat">( Alabama |
|||
Alaska |
|||
Arizona |
|||
Arkansas |
|||
California |
|||
Colorado |
|||
Connecticut |
|||
Delaware |
|||
Florida |
|||
Georgia |
|||
Hawaii |
|||
Idaho |
|||
Illinois |
|||
Indiana |
|||
Iowa |
|||
Kansas |
|||
Kentucky |
|||
Louisiana |
|||
Maine |
|||
Maryland |
|||
Massachusetts |
|||
Michigan |
|||
Minnesota |
|||
Mississippi |
|||
Missouri |
|||
Montana |
|||
Nebraska |
|||
Nevada |
|||
"New Hampshire" |
|||
"New Jersey" |
|||
"New Mexico" |
|||
"New York" |
|||
"North Carolina" |
|||
"North Dakota" |
|||
Ohio |
|||
Oklahoma |
|||
Oregon |
|||
Pennsylvania |
|||
"Rhode Island" |
|||
"South Carolina" |
|||
"South Dakota" |
|||
Tennessee |
|||
Texas |
|||
Utah |
|||
Vermont |
|||
Virginia |
|||
Washington |
|||
"West Virginia" |
|||
Wisconsin |
|||
Wyoming |
|||
: ?states |
|||
& "New Kory" "Wen Kory" "York New" "Kory New" "New Kory":?extrastates |
|||
& ( "State name puzzle" |
|||
= allStates State state statechars char |
|||
, A Z S1 S2 S3 S4 L1 L2 L3 L4 L12 |
|||
. 0:?allStates |
|||
& whl |
|||
' ( !arg:%?State ?arg |
|||
& low$!State:?state |
|||
& 0:?statechars |
|||
& whl |
|||
' ( @(!state:? (%@:~" ":?char) ?state) |
|||
& !char+!statechars:?statechars |
|||
) |
|||
& (!State.!statechars)+!allStates:?allStates |
|||
) |
|||
& ( !allStates |
|||
: ? |
|||
+ ?*(?S1.?L1) |
|||
+ ?A |
|||
+ ?*(?S2.?L2) |
|||
+ ( ?Z |
|||
& !L1+!L2:?L12 |
|||
& !A+!Z |
|||
: ? |
|||
+ ?*(?S3.?L3&!L12+-1*!L3:?L4) |
|||
+ ? |
|||
+ ? |
|||
* ( ?S4 |
|||
. !L4 |
|||
& out$(!S1 "+" !S2 "=" !S3 "+" !S4) |
|||
& ~ |
|||
) |
|||
+ ? |
|||
) |
|||
| out$"No more solutions" |
|||
) |
|||
) |
|||
& "State name puzzle"$!states |
|||
& "State name puzzle"$(!states !extrastates) |
|||
);</syntaxhighlight> |
|||
Output: |
|||
<pre>North Carolina + South Dakota = North Dakota + South Carolina |
|||
No more solutions |
|||
Kory New + New Kory = New York + Wen Kory |
|||
Kory New + New Kory = New York + York New |
|||
Kory New + New Kory = Wen Kory + York New |
|||
Kory New + New York = New Kory + Wen Kory |
|||
Kory New + New York = New Kory + York New |
|||
Kory New + New York = Wen Kory + York New |
|||
Kory New + Wen Kory = New Kory + New York |
|||
Kory New + Wen Kory = New Kory + York New |
|||
Kory New + Wen Kory = New York + York New |
|||
Kory New + York New = New Kory + New York |
|||
Kory New + York New = New Kory + Wen Kory |
|||
Kory New + York New = New York + Wen Kory |
|||
New Kory + New York = Wen Kory + York New |
|||
New Kory + Wen Kory = New York + York New |
|||
New Kory + York New = New York + Wen Kory |
|||
North Carolina + South Dakota = North Dakota + South Carolina |
|||
No more solutions</pre> |
|||
=={{header|C}}== |
|||
Sort by letter occurence and deal with dupes. |
|||
<syntaxhighlight lang="c">#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#define USE_FAKES 1 |
|||
const char *states[] = { |
|||
#if USE_FAKES |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory", |
|||
#endif |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", |
|||
"Delaware", |
|||
"Florida", "Georgia", "Hawaii", |
|||
"Idaho", "Illinois", "Indiana", "Iowa", |
|||
"Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", |
|||
"Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
}; |
|||
int n_states = sizeof(states)/sizeof(*states); |
|||
typedef struct { unsigned char c[26]; const char *name[2]; } letters; |
|||
void count_letters(letters *l, const char *s) |
|||
{ |
|||
int c; |
|||
if (!l->name[0]) l->name[0] = s; |
|||
else l->name[1] = s; |
|||
while ((c = *s++)) { |
|||
if (c >= 'a' && c <= 'z') l->c[c - 'a']++; |
|||
if (c >= 'A' && c <= 'Z') l->c[c - 'A']++; |
|||
} |
|||
} |
|||
int lcmp(const void *aa, const void *bb) |
|||
{ |
|||
int i; |
|||
const letters *a = aa, *b = bb; |
|||
for (i = 0; i < 26; i++) |
|||
if (a->c[i] > b->c[i]) return 1; |
|||
else if (a->c[i] < b->c[i]) return -1; |
|||
return 0; |
|||
} |
|||
int scmp(const void *a, const void *b) |
|||
{ |
|||
return strcmp(*(const char *const *)a, *(const char *const *)b); |
|||
} |
|||
void no_dup() |
|||
{ |
|||
int i, j; |
|||
qsort(states, n_states, sizeof(const char*), scmp); |
|||
for (i = j = 0; i < n_states;) { |
|||
while (++i < n_states && !strcmp(states[i], states[j])); |
|||
if (i < n_states) states[++j] = states[i]; |
|||
} |
|||
n_states = j + 1; |
|||
} |
|||
void find_mix() |
|||
{ |
|||
int i, j, n; |
|||
letters *l, *p; |
|||
no_dup(); |
|||
n = n_states * (n_states - 1) / 2; |
|||
p = l = calloc(n, sizeof(letters)); |
|||
for (i = 0; i < n_states; i++) |
|||
for (j = i + 1; j < n_states; j++, p++) { |
|||
count_letters(p, states[i]); |
|||
count_letters(p, states[j]); |
|||
} |
|||
qsort(l, n, sizeof(letters), lcmp); |
|||
for (j = 0; j < n; j++) { |
|||
for (i = j + 1; i < n && !lcmp(l + j, l + i); i++) { |
|||
if (l[j].name[0] == l[i].name[0] |
|||
|| l[j].name[1] == l[i].name[0] |
|||
|| l[j].name[1] == l[i].name[1]) |
|||
continue; |
|||
printf("%s + %s => %s + %s\n", |
|||
l[j].name[0], l[j].name[1], l[i].name[0], l[i].name[1]); |
|||
} |
|||
} |
|||
free(l); |
|||
} |
|||
int main(void) |
|||
{ |
|||
find_mix(); |
|||
return 0; |
|||
}</syntaxhighlight> |
|||
=={{header|C++}}== |
|||
Ported from C solution. |
|||
<syntaxhighlight lang="cpp">#include <algorithm> |
|||
#include <iostream> |
|||
#include <string> |
|||
#include <array> |
|||
#include <vector> |
|||
template<typename T> |
|||
T unique(T&& src) |
|||
{ |
|||
T retval(std::move(src)); |
|||
std::sort(retval.begin(), retval.end(), std::less<typename T::value_type>()); |
|||
retval.erase(std::unique(retval.begin(), retval.end()), retval.end()); |
|||
return retval; |
|||
} |
|||
#define USE_FAKES 1 |
|||
auto states = unique(std::vector<std::string>({ |
|||
#if USE_FAKES |
|||
"Slender Dragon", "Abalamara", |
|||
#endif |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", |
"California", "Colorado", "Connecticut", |
||
"Delaware", |
"Delaware", |
||
"Florida", "Georgia", "Hawaii", |
"Florida", "Georgia", "Hawaii", |
||
"Idaho", "Illinois", "Indiana", "Iowa", |
"Idaho", "Illinois", "Indiana", "Iowa", |
||
Line 32: | Line 450: | ||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
"South Carolina", "South Dakota", "Tennessee", "Texas", |
||
"Utah", "Vermont", "Virginia", |
"Utah", "Vermont", "Virginia", |
||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
||
})); |
|||
<br />Comma separated list of additional fictitious state names to be added to the original (Includes a duplicate):<pre>"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"</pre> |
|||
struct counted_pair |
|||
{ |
|||
std::string name; |
|||
std::array<int, 26> count{}; |
|||
void count_characters(const std::string& s) |
|||
{ |
|||
for (auto&& c : s) { |
|||
if (c >= 'a' && c <= 'z') count[c - 'a']++; |
|||
if (c >= 'A' && c <= 'Z') count[c - 'A']++; |
|||
} |
|||
} |
|||
counted_pair(const std::string& s1, const std::string& s2) |
|||
: name(s1 + " + " + s2) |
|||
{ |
|||
count_characters(s1); |
|||
count_characters(s2); |
|||
} |
|||
}; |
|||
bool operator<(const counted_pair& lhs, const counted_pair& rhs) |
|||
{ |
|||
auto lhs_size = lhs.name.size(); |
|||
auto rhs_size = rhs.name.size(); |
|||
return lhs_size == rhs_size |
|||
? std::lexicographical_compare(lhs.count.begin(), |
|||
lhs.count.end(), |
|||
rhs.count.begin(), |
|||
rhs.count.end()) |
|||
: lhs_size < rhs_size; |
|||
} |
|||
bool operator==(const counted_pair& lhs, const counted_pair& rhs) |
|||
{ |
|||
return lhs.name.size() == rhs.name.size() && lhs.count == rhs.count; |
|||
} |
|||
int main() |
|||
{ |
|||
const int n_states = states.size(); |
|||
std::vector<counted_pair> pairs; |
|||
for (int i = 0; i < n_states; i++) { |
|||
for (int j = 0; j < i; j++) { |
|||
pairs.emplace_back(counted_pair(states[i], states[j])); |
|||
} |
|||
} |
|||
std::sort(pairs.begin(), pairs.end()); |
|||
auto start = pairs.begin(); |
|||
while (true) { |
|||
auto match = std::adjacent_find(start, pairs.end()); |
|||
if (match == pairs.end()) { |
|||
break; |
|||
} |
|||
auto next = match + 1; |
|||
std::cout << match->name << " => " << next->name << "\n"; |
|||
start = next; |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|Clojure}}== |
|||
<syntaxhighlight lang="clojure">(ns clojure-sandbox.statenames |
|||
(:require [clojure.data.csv :as csv] |
|||
[clojure.java.io :as io] |
|||
[clojure.string :refer [lower-case]] |
|||
[clojure.math.combinatorics :as c] |
|||
[clojure.pprint :as pprint])) |
|||
(def made-up-states ["New Kory" "Wen Kory" "York New" "Kory New" "New Kory"]) |
|||
;; I saved the list of states in a local file to keep the code clean but you can copy and paste the list instead |
|||
(def real-states (with-open [in-file (io/reader (io/resource "states.csv"))] |
|||
(->> (doall |
|||
(csv/read-csv in-file)) |
|||
(map first)))) |
|||
(defn- state->charset [state-name] |
|||
"Convert state name into sorted list of characters with no spaces" |
|||
(->> state-name |
|||
char-array |
|||
sort |
|||
(filter (set (map char (range 97 123)))))) ;; ASCII range for lower case letters |
|||
(defn- add-charsets [states] |
|||
"Calculate sorted character list for each state and store with name" |
|||
(->> states |
|||
(map lower-case) ;; Convert all names to lower case |
|||
set ;; remove duplicates |
|||
(map |
|||
(fn [s] {:name s |
|||
:characters (state->charset s)})))) ;; add characters |
|||
(defn- pair-chars [state1 state2] |
|||
"Join the characters of two states together and sort them" |
|||
(-> state1 |
|||
:characters |
|||
(concat (:characters state2)) |
|||
sort)) |
|||
(defn- pair [[state1 state2]] |
|||
"Record representing two state names and the total characters used in them" |
|||
{:inputs [(:name state1) (:name state2)] |
|||
:characters (pair-chars state1 state2)}) |
|||
(defn- find-all-pairs [elements] |
|||
(c/combinations elements 2)) |
|||
(defn- pairs-to-search [state-names] |
|||
"Create character lists for all states and return a list of all possible pairs" |
|||
(->> state-names |
|||
add-charsets |
|||
find-all-pairs |
|||
(map pair))) |
|||
(defn- pairs-have-same-letters? [[pair1 pair2]] |
|||
(= (:characters pair1) (:characters pair2))) |
|||
(defn- inputs-are-distinct? [[pair1 pair2 :as pairs]] |
|||
"Check that two pairs of states don't contain the same state" |
|||
(= 4 ;; There should be a total of 4 distinct states in the two pairs |
|||
(->> pairs |
|||
(map :inputs) |
|||
flatten |
|||
set |
|||
count))) |
|||
(defn- search [pairs] |
|||
(->> pairs |
|||
find-all-pairs ;; find pairs of pairs to search |
|||
(filter pairs-have-same-letters?) ;; Keep only those where each pair has the same characters |
|||
(filter inputs-are-distinct?))) ;; Remove pairs with duplicate states |
|||
(defn find-matches [state-names] |
|||
"Find all state pairs and return pairs of them using the same letters" |
|||
(-> state-names |
|||
pairs-to-search |
|||
search)) |
|||
(defn- format-match-output [[pair1 pair2]] |
|||
"Format a pair of state pairs to print out" |
|||
(str (first (:inputs pair1)) |
|||
" + " |
|||
(last (:inputs pair1)) |
|||
" = " |
|||
(first (:inputs pair2)) |
|||
" + " |
|||
(last (:inputs pair2)))) |
|||
(defn- evaluate-and-print [states] |
|||
(->> states |
|||
find-matches |
|||
(map format-match-output) |
|||
pprint/pprint)) |
|||
(defn -main [& args] |
|||
(println "Solutions for 50 real states") |
|||
(evaluate-and-print real-states) |
|||
(println "Solutions with made up states added") |
|||
(evaluate-and-print (concat real-states made-up-states))) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Solutions for 50 real states |
|||
("north carolina + south dakota = south carolina + north dakota") |
|||
Solutions with made up states added |
|||
("new york + new kory = kory new + york new" |
|||
"new york + new kory = kory new + wen kory" |
|||
"new york + new kory = york new + wen kory" |
|||
"new york + kory new = new kory + york new" |
|||
"new york + kory new = new kory + wen kory" |
|||
"new york + kory new = york new + wen kory" |
|||
"new york + york new = new kory + kory new" |
|||
"new york + york new = new kory + wen kory" |
|||
"new york + york new = kory new + wen kory" |
|||
"new york + wen kory = new kory + kory new" |
|||
"new york + wen kory = new kory + york new" |
|||
"new york + wen kory = kory new + york new" |
|||
"north carolina + south dakota = south carolina + north dakota" |
|||
"new kory + kory new = york new + wen kory" |
|||
"new kory + york new = kory new + wen kory" |
|||
"new kory + wen kory = kory new + york new") |
|||
</pre> |
|||
=={{header|D}}== |
|||
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.string, std.exception; |
|||
auto states = ["Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", "Delaware", "Florida", |
|||
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", |
|||
"Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", |
|||
"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", |
|||
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", |
|||
"Oregon", "Pennsylvania", "Rhode Island", "South Carolina", |
|||
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming", |
|||
// Uncomment the next line for the fake states. |
|||
// "New Kory", "Wen Kory", "York New", "Kory New", "New Kory" |
|||
]; |
|||
void main() { |
|||
states.length -= states.sort().uniq.copy(states).length; |
|||
string[][const ubyte[]] smap; |
|||
foreach (immutable i, s1; states[0 .. $ - 1]) |
|||
foreach (s2; states[i + 1 .. $]) |
|||
smap[(s1 ~ s2).dup.representation.sort().release.assumeUnique] |
|||
~= s1 ~ " + " ~ s2; |
|||
writefln("%-(%-(%s = %)\n%)", |
|||
smap.values.sort().filter!q{ a.length > 1 }); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>North Carolina + South Dakota = North Dakota + South Carolina</pre> |
|||
=={{header|F_Sharp|F#}}== |
|||
<syntaxhighlight lang="fsharp"> |
|||
// State name puzzle. Nigel Galloway: February 9th., 2023 |
|||
let states=["Alabama"; "Alaska"; "Arizona"; "Arkansas"; "California"; "Colorado"; "Connecticut"; "Delaware"; "Florida"; "Georgia"; "Hawaii"; "Idaho"; "Illinois"; "Indiana"; "Iowa"; "Kansas"; "Kentucky"; "Louisiana"; "Maine"; "Maryland"; "Massachusetts"; "Michigan"; "Minnesota"; "Mississippi"; "Missouri"; "Montana"; "Nebraska"; "Nevada"; "New Hampshire"; "New Jersey"; "New Mexico"; "New York"; "North Carolina"; "North Dakota"; "Ohio"; "Oklahoma"; "Oregon"; "Pennsylvania"; "Rhode Island"; "South Carolina"; "South Dakota"; "Tennessee"; "Texas"; "Utah"; "Vermont"; "Virginia"; "Washington"; "West Virginia"; "Wisconsin"; "Wyoming"; "New Kory"; "Wen Kory"; "York New"; "Kory New"; "New Kory"]|>List.distinct |
|||
let fN(i,g)(e,l)=let n=Array.zeroCreate<int>256 |
|||
let fN i g=n[g]<-n[g]+i |
|||
let fG n g=(g:string).ToLower().ToCharArray()|>Array.iter(fun g->fN n (int g)) |
|||
fG 1 i; fG 1 g; fG -1 e; fG -1 l; n|>Array.forall((=)0) |
|||
let n=states|>List.allPairs states|>List.filter(fun(n,g)->n<g)|>List.groupBy(fun(n,g)->n.Length+g.Length) |
|||
let g=n|>List.map(fun(_,n)->n|>List.allPairs n|>List.filter(fun((n,g),(n',g'))->(n,g)<(n',g') && n<>n' && n<>g' && g<>n' && g<>g' && fN(n,g)(n',g')))|>List.filter(List.isEmpty>>not) |
|||
g|>List.iter(List.iter(fun((i,g),(e,l))->printfn $"%s{i},%s{g}->%s{e},%s{l}")) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
New Kory,New York->Wen Kory,York New |
|||
New Kory,Wen Kory->New York,York New |
|||
New Kory,York New->New York,Wen Kory |
|||
Kory New,New York->New Kory,Wen Kory |
|||
Kory New,New York->New Kory,York New |
|||
Kory New,New York->Wen Kory,York New |
|||
Kory New,New Kory->New York,Wen Kory |
|||
Kory New,New Kory->New York,York New |
|||
Kory New,New Kory->Wen Kory,York New |
|||
Kory New,Wen Kory->New York,York New |
|||
Kory New,Wen Kory->New Kory,New York |
|||
Kory New,Wen Kory->New Kory,York New |
|||
Kory New,York New->New York,Wen Kory |
|||
Kory New,York New->New Kory,New York |
|||
Kory New,York New->New Kory,Wen Kory |
|||
North Carolina,South Dakota->North Dakota,South Carolina |
|||
</pre> |
|||
=={{header|Go}}== |
|||
<syntaxhighlight lang="go">package main |
|||
import ( |
|||
"fmt" |
|||
"unicode" |
|||
) |
|||
var states = []string{"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", |
|||
"Delaware", |
|||
"Florida", "Georgia", "Hawaii", |
|||
"Idaho", "Illinois", "Indiana", "Iowa", |
|||
"Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", |
|||
"Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming"} |
|||
func main() { |
|||
play(states) |
|||
play(append(states, |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory")) |
|||
} |
|||
func play(states []string) { |
|||
fmt.Println(len(states), "states:") |
|||
// get list of unique state names |
|||
set := make(map[string]bool, len(states)) |
|||
for _, s := range states { |
|||
set[s] = true |
|||
} |
|||
// make parallel arrays for unique state names and letter histograms |
|||
s := make([]string, len(set)) |
|||
h := make([][26]byte, len(set)) |
|||
var i int |
|||
for us := range set { |
|||
s[i] = us |
|||
for _, c := range us { |
|||
if u := uint(unicode.ToLower(c)) - 'a'; u < 26 { |
|||
h[i][u]++ |
|||
} |
|||
} |
|||
i++ |
|||
} |
|||
// use map to find matches. map key is sum of histograms of |
|||
// two different states. map value is indexes of the two states. |
|||
type pair struct { |
|||
i1, i2 int |
|||
} |
|||
m := make(map[string][]pair) |
|||
b := make([]byte, 26) // buffer for summing histograms |
|||
for i1, h1 := range h { |
|||
for i2 := i1 + 1; i2 < len(h); i2++ { |
|||
// sum histograms |
|||
for i := range b { |
|||
b[i] = h1[i] + h[i2][i] |
|||
} |
|||
k := string(b) // make key from buffer. |
|||
// now loop over any existing pairs with the same key, |
|||
// printing any where both states of this pair are different |
|||
// than the states of the existing pair |
|||
for _, x := range m[k] { |
|||
if i1 != x.i1 && i1 != x.i2 && i2 != x.i1 && i2 != x.i2 { |
|||
fmt.Printf("%s, %s = %s, %s\n", s[i1], s[i2], |
|||
s[x.i1], s[x.i2]) |
|||
} |
|||
} |
|||
// store this pair in the map whether printed or not. |
|||
m[k] = append(m[k], pair{i1, i2}) |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
50 states: |
|||
North Dakota, South Carolina = North Carolina, South Dakota |
|||
55 states: |
|||
South Dakota, North Carolina = North Dakota, South Carolina |
|||
New Kory, Kory New = Wen Kory, York New |
|||
New Kory, Kory New = Wen Kory, New York |
|||
New Kory, York New = Wen Kory, Kory New |
|||
New Kory, York New = Wen Kory, New York |
|||
New Kory, New York = Wen Kory, Kory New |
|||
New Kory, New York = Wen Kory, York New |
|||
Kory New, York New = Wen Kory, New Kory |
|||
Kory New, York New = Wen Kory, New York |
|||
Kory New, York New = New Kory, New York |
|||
Kory New, New York = Wen Kory, New Kory |
|||
Kory New, New York = Wen Kory, York New |
|||
Kory New, New York = New Kory, York New |
|||
York New, New York = Wen Kory, New Kory |
|||
York New, New York = Wen Kory, Kory New |
|||
York New, New York = New Kory, Kory New |
|||
</pre> |
|||
=={{header|Haskell}}== |
|||
<syntaxhighlight lang="haskell">{-# LANGUAGE TupleSections #-} |
|||
import Data.Char (isLetter, toLower) |
|||
import Data.Function (on) |
|||
import Data.List (groupBy, nub, sort, sortBy) |
|||
-------------------- STATE NAME PUZZLE ------------------- |
|||
puzzle :: [String] -> [((String, String), (String, String))] |
|||
puzzle states = |
|||
concatMap |
|||
((filter isValid . pairs) . map snd) |
|||
( filter ((> 1) . length) $ |
|||
groupBy ((==) `on` fst) $ |
|||
sortBy |
|||
(compare `on` fst) |
|||
[ (pkey (a <> b), (a, b)) |
|||
| (a, b) <- pairs (nub $ sort states) |
|||
] |
|||
) |
|||
where |
|||
pkey = sort . filter isLetter . map toLower |
|||
isValid ((a0, a1), (b0, b1)) = |
|||
(a0 /= b0) |
|||
&& (a0 /= b1) |
|||
&& (a1 /= b0) |
|||
&& (a1 /= b1) |
|||
pairs :: [a] -> [(a, a)] |
|||
pairs [] = [] |
|||
pairs (y : ys) = map (y,) ys <> pairs ys |
|||
--------------------------- TEST ------------------------- |
|||
main :: IO () |
|||
main = do |
|||
putStrLn $ |
|||
"Matching pairs generated from " |
|||
<> show (length stateNames) |
|||
<> " state names and " |
|||
<> show (length fakeStateNames) |
|||
<> " fake state names:" |
|||
mapM_ print $ puzzle $ stateNames <> fakeStateNames |
|||
stateNames :: [String] |
|||
stateNames = |
|||
[ "Alabama", |
|||
"Alaska", |
|||
"Arizona", |
|||
"Arkansas", |
|||
"California", |
|||
"Colorado", |
|||
"Connecticut", |
|||
"Delaware", |
|||
"Florida", |
|||
"Georgia", |
|||
"Hawaii", |
|||
"Idaho", |
|||
"Illinois", |
|||
"Indiana", |
|||
"Iowa", |
|||
"Kansas", |
|||
"Kentucky", |
|||
"Louisiana", |
|||
"Maine", |
|||
"Maryland", |
|||
"Massachusetts", |
|||
"Michigan", |
|||
"Minnesota", |
|||
"Mississippi", |
|||
"Missouri", |
|||
"Montana", |
|||
"Nebraska", |
|||
"Nevada", |
|||
"New Hampshire", |
|||
"New Jersey", |
|||
"New Mexico", |
|||
"New York", |
|||
"North Carolina", |
|||
"North Dakota", |
|||
"Ohio", |
|||
"Oklahoma", |
|||
"Oregon", |
|||
"Pennsylvania", |
|||
"Rhode Island", |
|||
"South Carolina", |
|||
"South Dakota", |
|||
"Tennessee", |
|||
"Texas", |
|||
"Utah", |
|||
"Vermont", |
|||
"Virginia", |
|||
"Washington", |
|||
"West Virginia", |
|||
"Wisconsin", |
|||
"Wyoming" |
|||
] |
|||
fakeStateNames :: [String] |
|||
fakeStateNames = |
|||
[ "New Kory", |
|||
"Wen Kory", |
|||
"York New", |
|||
"Kory New", |
|||
"New Kory" |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre style="font-size:80%">Matching pairs generated from 50 state names and 5 fake state names: |
|||
(("North Carolina","South Dakota"),("North Dakota","South Carolina")) |
|||
(("Kory New","New Kory"),("New York","Wen Kory")) |
|||
(("Kory New","New Kory"),("New York","York New")) |
|||
(("Kory New","New Kory"),("Wen Kory","York New")) |
|||
(("Kory New","New York"),("New Kory","Wen Kory")) |
|||
(("Kory New","New York"),("New Kory","York New")) |
|||
(("Kory New","New York"),("Wen Kory","York New")) |
|||
(("Kory New","Wen Kory"),("New Kory","New York")) |
|||
(("Kory New","Wen Kory"),("New Kory","York New")) |
|||
(("Kory New","Wen Kory"),("New York","York New")) |
|||
(("Kory New","York New"),("New Kory","New York")) |
|||
(("Kory New","York New"),("New Kory","Wen Kory")) |
|||
(("Kory New","York New"),("New York","Wen Kory")) |
|||
(("New Kory","New York"),("Wen Kory","York New")) |
|||
(("New Kory","Wen Kory"),("New York","York New")) |
|||
(("New Kory","York New"),("New York","Wen Kory")) |
|||
</pre> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
=== Equivalence Class Solution === |
=== Equivalence Class Solution === |
||
< |
<syntaxhighlight lang="icon">link strings # for csort and deletec |
||
procedure main(arglist) |
procedure main(arglist) |
||
Line 85: | Line 977: | ||
} |
} |
||
write("... runtime ",(&time - st)/1000.,"\n",m," matches found.") |
write("... runtime ",(&time - st)/1000.,"\n",m," matches found.") |
||
end</ |
end</syntaxhighlight> |
||
The following are common routines:< |
The following are common routines:<syntaxhighlight lang="icon">procedure getStates() # return list of state names |
||
return ["Alabama", "Alaska", "Arizona", "Arkansas", |
return ["Alabama", "Alaska", "Arizona", "Arkansas", |
||
"California", "Colorado", "Connecticut", |
"California", "Colorado", "Connecticut", |
||
Line 107: | Line 999: | ||
procedure getStates2() # return list of state names + fictious states |
procedure getStates2() # return list of state names + fictious states |
||
return getStates() ||| ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"] |
return getStates() ||| ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"] |
||
end</ |
end</syntaxhighlight> |
||
=== Godel Number Solution === |
=== Godel Number Solution === |
||
< |
<syntaxhighlight lang="icon">link factors |
||
procedure GNsolve(S) |
procedure GNsolve(S) |
||
Line 167: | Line 1,059: | ||
every z *:= xlate[!s] |
every z *:= xlate[!s] |
||
return z |
return z |
||
end</ |
end</syntaxhighlight> |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
Line 211: | Line 1,103: | ||
kory new:york new and new kory:new york |
kory new:york new and new kory:new york |
||
Time: 0.018</pre> |
Time: 0.018</pre> |
||
=={{header|J}}== |
|||
Implementation: |
|||
<syntaxhighlight lang="j">require'strings stats' |
|||
states=:<;._2]0 :0-.LF |
|||
Alabama,Alaska,Arizona,Arkansas,California,Colorado, |
|||
Connecticut,Delaware,Florida,Georgia,Hawaii,Idaho, |
|||
Illinois,Indiana,Iowa,Kansas,Kentucky,Louisiana, |
|||
Maine,Maryland,Massachusetts,Michigan,Minnesota, |
|||
Mississippi,Missouri,Montana,Nebraska,Nevada, |
|||
New Hampshire,New Jersey,New Mexico,New York, |
|||
North Carolina,North Dakota,Ohio,Oklahoma,Oregon, |
|||
Pennsylvania,Rhode Island,South Carolina, |
|||
South Dakota,Tennessee,Texas,Utah,Vermont,Virginia, |
|||
Washington,West Virginia,Wisconsin,Wyoming, |
|||
Maine,Maine,Maine,Maine,Maine,Maine,Maine,Maine, |
|||
) |
|||
pairUp=: (#~ matchUp)@({~ 2 comb #)@~. |
|||
matchUp=: (i.~ ~: i:~)@:(<@normalize@;"1) |
|||
normalize=: /:~@tolower@-.&' '</syntaxhighlight> |
|||
In action: |
|||
<syntaxhighlight lang="j"> pairUp states |
|||
┌──────────────┬──────────────┐ |
|||
│North Carolina│South Dakota │ |
|||
├──────────────┼──────────────┤ |
|||
│North Dakota │South Carolina│ |
|||
└──────────────┴──────────────┘</syntaxhighlight> |
|||
Note: this approach is sufficient to solve the original problem, but does not properly deal with the addition of fictitious states. So: |
|||
<syntaxhighlight lang="j">isolatePairs=: ~.@matchUp2@(#~ *./@matchUp"2)@({~ 2 comb #) |
|||
matchUp2=: /:~"2@:(/:~"1)@(#~ 4=#@~.@,"2)</syntaxhighlight> |
|||
In action: |
|||
<syntaxhighlight lang="j"> isolatePairs pairUp 'New Kory';'Wen Kory';'York New';'Kory New';'New Kory';states |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │York New │ |
|||
├──────────────┼──────────────┤ |
|||
│New Kory │Wen Kory │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│New Kory │Wen Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│New York │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │New York │ |
|||
├──────────────┼──────────────┤ |
|||
│New Kory │Wen Kory │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │Wen Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│New Kory │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│New Kory │York New │ |
|||
├──────────────┼──────────────┤ |
|||
│New York │Wen Kory │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │New York │ |
|||
├──────────────┼──────────────┤ |
|||
│New Kory │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │New Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│Wen Kory │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │New Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│New York │Wen Kory │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │New Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│New York │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│New Kory │New York │ |
|||
├──────────────┼──────────────┤ |
|||
│Wen Kory │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │Wen Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│New Kory │New York │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │York New │ |
|||
├──────────────┼──────────────┤ |
|||
│New Kory │New York │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │New York │ |
|||
├──────────────┼──────────────┤ |
|||
│Wen Kory │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │Wen Kory │ |
|||
├──────────────┼──────────────┤ |
|||
│New York │York New │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│Kory New │York New │ |
|||
├──────────────┼──────────────┤ |
|||
│New York │Wen Kory │ |
|||
└──────────────┴──────────────┘ |
|||
┌──────────────┬──────────────┐ |
|||
│North Carolina│South Dakota │ |
|||
├──────────────┼──────────────┤ |
|||
│North Dakota │South Carolina│ |
|||
└──────────────┴──────────────┘</syntaxhighlight> |
|||
=={{header|Java}}== |
|||
{{works with|Java|8}} |
|||
<syntaxhighlight lang="java">import java.util.*; |
|||
import java.util.stream.*; |
|||
public class StateNamePuzzle { |
|||
static String[] states = {"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", "Delaware", "Florida", |
|||
"Georgia", "hawaii", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", |
|||
"Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", |
|||
"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", |
|||
"New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", |
|||
"Oregon", "Pennsylvania", "Rhode Island", "South Carolina", |
|||
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming", |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory",}; |
|||
public static void main(String[] args) { |
|||
solve(Arrays.asList(states)); |
|||
} |
|||
static void solve(List<String> input) { |
|||
Map<String, String> orig = input.stream().collect(Collectors.toMap( |
|||
s -> s.replaceAll("\\s", "").toLowerCase(), s -> s, (s, a) -> s)); |
|||
input = new ArrayList<>(orig.keySet()); |
|||
Map<String, List<String[]>> map = new HashMap<>(); |
|||
for (int i = 0; i < input.size() - 1; i++) { |
|||
String pair0 = input.get(i); |
|||
for (int j = i + 1; j < input.size(); j++) { |
|||
String[] pair = {pair0, input.get(j)}; |
|||
String s = pair0 + pair[1]; |
|||
String key = Arrays.toString(s.chars().sorted().toArray()); |
|||
List<String[]> val = map.getOrDefault(key, new ArrayList<>()); |
|||
val.add(pair); |
|||
map.put(key, val); |
|||
} |
|||
} |
|||
map.forEach((key, list) -> { |
|||
for (int i = 0; i < list.size() - 1; i++) { |
|||
String[] a = list.get(i); |
|||
for (int j = i + 1; j < list.size(); j++) { |
|||
String[] b = list.get(j); |
|||
if (Stream.of(a[0], a[1], b[0], b[1]).distinct().count() < 4) |
|||
continue; |
|||
System.out.printf("%s + %s = %s + %s %n", orig.get(a[0]), |
|||
orig.get(a[1]), orig.get(b[0]), orig.get(b[1])); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>Wen Kory + Kory New = York New + New Kory |
|||
Wen Kory + Kory New = York New + New York |
|||
Wen Kory + Kory New = New Kory + New York |
|||
Wen Kory + York New = Kory New + New Kory |
|||
Wen Kory + York New = Kory New + New York |
|||
Wen Kory + York New = New Kory + New York |
|||
Wen Kory + New Kory = Kory New + York New |
|||
Wen Kory + New Kory = Kory New + New York |
|||
Wen Kory + New Kory = York New + New York |
|||
Wen Kory + New York = Kory New + York New |
|||
Wen Kory + New York = Kory New + New Kory |
|||
Wen Kory + New York = York New + New Kory |
|||
Kory New + York New = New Kory + New York |
|||
Kory New + New Kory = York New + New York |
|||
Kory New + New York = York New + New Kory |
|||
South Dakota + North Carolina = North Dakota + South Carolina </pre> |
|||
=={{header|jq}}== |
|||
{{works with|jq|1.4}} |
|||
<syntaxhighlight lang="jq"># Input: a string |
|||
# Output: an array, being the exploded form of the normalized input |
|||
def normalize: |
|||
explode |
|||
| map(if . >= 97 then (. - 97) elif . >= 65 then (. - 65) else empty end); |
|||
# Input: an array of strings |
|||
# Output: a dictionary with key:value pairs: normalizedString:string |
|||
def dictionary: |
|||
reduce .[] as $s ( {}; . + { ($s|normalize|implode): $s }); |
|||
# Input: an array of strings (e.g. state names) |
|||
# Output: a stream of solutions |
|||
def solve: |
|||
# Given a pair of normalized state names as lists of integers: |
|||
def nletters: map(length) | add; |
|||
# input [[s1,s2], [t2,t2]] |
|||
def solved: |
|||
( .[0] | add | sort) == (.[1] | add | sort); |
|||
unique |
|||
| length as $l |
|||
| dictionary as $dictionary |
|||
| ($dictionary | keys | map(explode)) as $states |
|||
| reduce ( range(0; $l) as $s1 |
|||
| range($s1+1; $l) as $s2 |
|||
| range($s1+1; $l) as $t1 |
|||
| select($s2 != $t1) |
|||
| range($t1+1; $l) as $t2 |
|||
| select($s2 != $t2) |
|||
| [[$states[$s1], $states[$s2]], [$states[$t1], $states[$t2]]] ) as $quad |
|||
([]; |
|||
if ($quad[0] | nletters) == ($quad[1] | nletters) |
|||
and ($quad | solved) |
|||
then . + [$quad | map( map( $dictionary[ implode ] ))] |
|||
else . |
|||
end) |
|||
| .[];</syntaxhighlight> |
|||
'''The task:''' |
|||
<syntaxhighlight lang="jq">def States: [ |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", |
|||
"Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", |
|||
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", |
|||
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", |
|||
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", |
|||
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", |
|||
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
]; |
|||
def task: |
|||
"Real state names:", |
|||
(States | solve), |
|||
"", |
|||
"States together with fictional state names:", |
|||
(States + ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"] | solve) ; |
|||
task</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight lang="sh">$ jq -c -n -r -f State_name_puzzle.jq |
|||
Real state names: |
|||
[["North Carolina","South Dakota"],["North Dakota","South Carolina"]] |
|||
States together with fictional state names: |
|||
[["Kory New","New Kory"],["New York","Wen Kory"]] |
|||
[["Kory New","New Kory"],["New York","York New"]] |
|||
[["Kory New","New Kory"],["Wen Kory","York New"]] |
|||
[["Kory New","New York"],["New Kory","Wen Kory"]] |
|||
[["Kory New","New York"],["New Kory","York New"]] |
|||
[["Kory New","New York"],["Wen Kory","York New"]] |
|||
[["Kory New","Wen Kory"],["New Kory","New York"]] |
|||
[["Kory New","Wen Kory"],["New Kory","York New"]] |
|||
[["Kory New","Wen Kory"],["New York","York New"]] |
|||
[["Kory New","York New"],["New Kory","New York"]] |
|||
[["Kory New","York New"],["New Kory","Wen Kory"]] |
|||
[["Kory New","York New"],["New York","Wen Kory"]] |
|||
[["New Kory","New York"],["Wen Kory","York New"]] |
|||
[["New Kory","Wen Kory"],["New York","York New"]] |
|||
[["New Kory","York New"],["New York","Wen Kory"]] |
|||
[["North Carolina","South Dakota"],["North Dakota","South Carolina"]]</syntaxhighlight> |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|0.6}} |
|||
{{trans|Kotlin}} |
|||
'''Module''': |
|||
<syntaxhighlight lang="julia">module StateNamePuzzle |
|||
const realnames = ["Alabama", "Alaska", "Arizona", "Arkansas", "California", |
|||
"Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", |
|||
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", |
|||
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", |
|||
"Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", |
|||
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", |
|||
"Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", |
|||
"Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", |
|||
"Wisconsin", "Wyoming"] |
|||
const fictitious = ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"] |
|||
function combine(a::AbstractString, b::AbstractString) |
|||
chars = vcat(collect(Char, a), collect(Char, b)) |
|||
sort!(chars) |
|||
return join(chars) |
|||
end |
|||
function solve(input::Vector{<:AbstractString}) |
|||
dict = Dict{String,String}() |
|||
for state in input |
|||
key = replace(state, " ", "") |> lowercase |
|||
if !haskey(dict, key) |
|||
dict[key] = state |
|||
end |
|||
end |
|||
keyset = collect(keys(dict)) |
|||
solutions = String[] |
|||
duplicates = String[] |
|||
for i in eachindex(keyset), j in (i+1):endof(keyset) |
|||
len1 = length(keyset[i]) + length(keyset[j]) |
|||
combined1 = combine(keyset[i], keyset[j]) |
|||
for k in eachindex(keyset), l in k+1:endof(keyset) |
|||
k ∈ (i, j) && continue |
|||
l ∈ (i, j) && continue |
|||
len2 = length(keyset[k]) + length(keyset[l]) |
|||
len1 != len2 && continue |
|||
combined2 = combine(keyset[k], keyset[l]) |
|||
if combined1 == combined2 |
|||
f1 = dict[keyset[i]] * " + " * dict[keyset[j]] |
|||
f2 = dict[keyset[k]] * " + " * dict[keyset[l]] |
|||
f3 = f1 * " = " * f2 |
|||
f3 ∈ duplicates && continue |
|||
push!(solutions, f3) |
|||
f4 = f2 * " = " * f1 |
|||
push!(duplicates, f4) |
|||
end |
|||
end |
|||
end |
|||
return sort!(solutions) |
|||
end |
|||
end # module StateNamePuzzle</syntaxhighlight> |
|||
'''Main''': |
|||
<syntaxhighlight lang="julia">println("Real states:") |
|||
foreach(println, StateNamePuzzle.solve(StateNamePuzzle.realnames)) |
|||
println("\nReal + fictitious state:") |
|||
foreach(println, StateNamePuzzle.solve(vcat(StateNamePuzzle.realnames, |
|||
StateNamePuzzle.fictitious)))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Real states: |
|||
South Dakota + North Carolina = South Carolina + North Dakota |
|||
Real + fictitious state: |
|||
Kory New + New Kory = New York + York New |
|||
Kory New + New Kory = Wen Kory + New York |
|||
Kory New + New Kory = Wen Kory + York New |
|||
Kory New + New York = New Kory + Wen Kory |
|||
Kory New + New York = New Kory + York New |
|||
Kory New + New York = Wen Kory + York New |
|||
Kory New + Wen Kory = New Kory + New York |
|||
Kory New + Wen Kory = New Kory + York New |
|||
Kory New + Wen Kory = New York + York New |
|||
Kory New + York New = New Kory + New York |
|||
Kory New + York New = New Kory + Wen Kory |
|||
Kory New + York New = Wen Kory + New York |
|||
New Kory + New York = Wen Kory + York New |
|||
New Kory + Wen Kory = New York + York New |
|||
New Kory + York New = Wen Kory + New York |
|||
South Dakota + North Carolina = South Carolina + North Dakota</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.2.10 |
|||
fun solve(states: List<String>) { |
|||
val dict = mutableMapOf<String, String>() |
|||
for (state in states) { |
|||
val key = state.toLowerCase().replace(" ", "") |
|||
if (dict[key] == null) dict.put(key, state) |
|||
} |
|||
val keys = dict.keys.toList() |
|||
val solutions = mutableListOf<String>() |
|||
val duplicates = mutableListOf<String>() |
|||
for (i in 0 until keys.size) { |
|||
for (j in i + 1 until keys.size) { |
|||
val len = keys[i].length + keys[j].length |
|||
val chars = (keys[i] + keys[j]).toCharArray() |
|||
chars.sort() |
|||
val combined = String(chars) |
|||
for (k in 0 until keys.size) { |
|||
for (l in k + 1 until keys.size) { |
|||
if (k == i || k == j || l == i || l == j) continue |
|||
val len2 = keys[k].length + keys[l].length |
|||
if (len2 != len) continue |
|||
val chars2 = (keys[k] + keys[l]).toCharArray() |
|||
chars2.sort() |
|||
val combined2 = String(chars2) |
|||
if (combined == combined2) { |
|||
val f1 = "${dict[keys[i]]} + ${dict[keys[j]]}" |
|||
val f2 = "${dict[keys[k]]} + ${dict[keys[l]]}" |
|||
val f3 = "$f1 = $f2" |
|||
if (f3 in duplicates) continue |
|||
solutions.add(f3) |
|||
val f4 = "$f2 = $f1" |
|||
duplicates.add(f4) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
solutions.sort() |
|||
for ((i, sol) in solutions.withIndex()) { |
|||
println("%2d %s".format(i + 1, sol)) |
|||
} |
|||
} |
|||
fun main(args: Array<String>) { |
|||
val states = listOf( |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", |
|||
"Delaware", |
|||
"Florida", "Georgia", "Hawaii", |
|||
"Idaho", "Illinois", "Indiana", "Iowa", |
|||
"Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", |
|||
"Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
) |
|||
println("Real states only:") |
|||
solve(states) |
|||
println() |
|||
val fictitious = listOf( |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory" |
|||
) |
|||
println("Real and fictitious states:") |
|||
solve(states + fictitious) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Real states only: |
|||
1 North Carolina + South Dakota = North Dakota + South Carolina |
|||
Real and fictitious states: |
|||
1 New Kory + Kory New = Wen Kory + York New |
|||
2 New Kory + Wen Kory = York New + Kory New |
|||
3 New Kory + York New = Wen Kory + Kory New |
|||
4 New York + Kory New = New Kory + Wen Kory |
|||
5 New York + Kory New = New Kory + York New |
|||
6 New York + Kory New = Wen Kory + York New |
|||
7 New York + New Kory = Wen Kory + Kory New |
|||
8 New York + New Kory = Wen Kory + York New |
|||
9 New York + New Kory = York New + Kory New |
|||
10 New York + Wen Kory = New Kory + Kory New |
|||
11 New York + Wen Kory = New Kory + York New |
|||
12 New York + Wen Kory = York New + Kory New |
|||
13 New York + York New = New Kory + Kory New |
|||
14 New York + York New = New Kory + Wen Kory |
|||
15 New York + York New = Wen Kory + Kory New |
|||
16 North Carolina + South Dakota = North Dakota + South Carolina |
|||
</pre> |
|||
=={{header|LiveCode}}== |
|||
This is going to be O(N^2). |
|||
<syntaxhighlight lang="livecode">function pairwiseAnagrams X |
|||
if the optionkey is down then breakpoint |
|||
put the long seconds into T |
|||
put empty into itemsSoFar |
|||
repeat for each item W in X |
|||
put word 1 to -1 of W into W |
|||
if D[W] = 1 then next repeat |
|||
put 1 into D[W] |
|||
repeat for each item W2 in itemsSoFar |
|||
put W,W2 & cr after WPairs[sortChars(W & W2,true)] |
|||
end repeat |
|||
put W & comma after itemsSoFar |
|||
end repeat |
|||
repeat for each key K in WPairs |
|||
put empty into pairsSoFar |
|||
repeat for each line L in WPairs[K] |
|||
repeat for each line L2 in pairsSoFar |
|||
if item 1 of L is among the items of L2 or item 2 of L is among the items of L2 then next repeat |
|||
put L && "and" && L2 & cr after R |
|||
end repeat |
|||
put L & cr after pairsSoFar |
|||
end repeat |
|||
end repeat |
|||
put the long seconds - T |
|||
return char 1 to -2 of R |
|||
end pairwiseAnagrams |
|||
function sortChars X,lettersOnly |
|||
get charsToItems(X,lettersOnly) |
|||
sort items of it |
|||
return itemsToChars(it) |
|||
end sortChars |
|||
function charsToItems X,lettersOnly |
|||
repeat for each char C in X |
|||
if lettersOnly and C is not in "abcdefghijklmnopqrstuvwxyz" then next repeat |
|||
put C & comma after R |
|||
end repeat |
|||
return char 1 to -2 of R |
|||
end charsToItems |
|||
function itemsToChars X |
|||
replace comma with empty in X |
|||
return X |
|||
end itemsToChars</syntaxhighlight> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
<syntaxhighlight lang="mathematica">letters[words_,n_] := Sort[Flatten[Characters /@ Take[words,n]]]; |
|||
groupSameQ[g1_, g2_] := Sort /@ Partition[g1, 2] === Sort /@ Partition[g2, 2]; |
|||
permutations[{a_, b_, c_, d_}] = Union[Permutations[{a, b, c, d}], SameTest -> groupSameQ]; |
|||
Select[Flatten[permutations /@ |
|||
Subsets[Union[ToLowerCase/@{"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", |
|||
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", |
|||
"Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", |
|||
"New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", |
|||
"Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", |
|||
"West Virginia", "Wisconsin", "Wyoming"}], {4}], 1], |
|||
letters[#, 2] === letters[#, -2] &]</syntaxhighlight> |
|||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="nim">import algorithm, sequtils, strformat, strutils, tables |
|||
const |
|||
States = @["Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", "Delaware", |
|||
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois", |
|||
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming"] |
|||
Fictitious = @["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"] |
|||
type MatchingPairs = ((string, string), (string, string)) |
|||
proc matchingPairs(states: openArray[string]): seq[MatchingPairs] = |
|||
## Build the list of matching pairs of states. |
|||
let states = sorted(states).deduplicate() |
|||
# Build a mapping from ordered sequence of chars to sequence of (state, state). |
|||
var mapping: Table[seq[char], seq[(string, string)]] |
|||
for i in 0..<states.high: |
|||
let s1 = states[i] |
|||
for j in (i + 1)..states.high: |
|||
let s2 = states[j] |
|||
mapping.mgetOrPut(sorted(map(s1 & s2, toLowerAscii)), @[]).add (s1, s2) |
|||
# Keep only the couples of pairs of states with no common state. |
|||
for pairs in mapping.values: |
|||
if pairs.len > 1: |
|||
# These pairs are candidates. |
|||
for i in 0..<pairs.high: |
|||
let pair1 = pairs[i] |
|||
for j in i..pairs.high: |
|||
let pair2 = pairs[j] |
|||
if pair1[0] != pair2[0] and pair1[0] != pair2[1] and |
|||
pair1[1] != pair2[0] and pair1[1] != pair2[1]: |
|||
# "pair1" and "pair2" have no common state. |
|||
result.add (pair1, pair2) |
|||
proc `$`(pairs: MatchingPairs): string = |
|||
## Return the string representation of two matching pairs. |
|||
"$1 & $2 = $3 & $4".format(pairs[0][0], pairs[0][1], pairs[1][0], pairs[1][1]) |
|||
echo "For real states:" |
|||
for n, pairs in matchingPairs(States): |
|||
echo &"{n+1:2}: {pairs}" |
|||
echo() |
|||
echo "For real + fictitious states:" |
|||
for n, pairs in matchingPairs(States & Fictitious): |
|||
echo &"{n+1:2}: {pairs}"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>For real states: |
|||
1: North Carolina & South Dakota = North Dakota & South Carolina |
|||
For real + fictitious states: |
|||
1: North Carolina & South Dakota = North Dakota & South Carolina |
|||
2: Kory New & New Kory = New York & Wen Kory |
|||
3: Kory New & New Kory = New York & York New |
|||
4: Kory New & New Kory = Wen Kory & York New |
|||
5: Kory New & New York = New Kory & Wen Kory |
|||
6: Kory New & New York = New Kory & York New |
|||
7: Kory New & New York = Wen Kory & York New |
|||
8: Kory New & Wen Kory = New Kory & New York |
|||
9: Kory New & Wen Kory = New Kory & York New |
|||
10: Kory New & Wen Kory = New York & York New |
|||
11: Kory New & York New = New Kory & New York |
|||
12: Kory New & York New = New Kory & Wen Kory |
|||
13: Kory New & York New = New York & Wen Kory |
|||
14: New Kory & New York = Wen Kory & York New |
|||
15: New Kory & Wen Kory = New York & York New |
|||
16: New Kory & York New = New York & Wen Kory</pre> |
|||
=={{header|Perl}}== |
|||
<syntaxhighlight lang="perl">#!/usr/bin/perl |
|||
use warnings; |
|||
use strict; |
|||
use feature qw{ say }; |
|||
sub uniq { |
|||
my %uniq; |
|||
undef @uniq{ @_ }; |
|||
return keys %uniq |
|||
} |
|||
sub puzzle { |
|||
my @states = uniq(@_); |
|||
my %pairs; |
|||
for my $state1 (@states) { |
|||
for my $state2 (@states) { |
|||
next if $state1 le $state2; |
|||
my $both = join q(), |
|||
grep ' ' ne $_, |
|||
sort split //, |
|||
lc "$state1$state2"; |
|||
push @{ $pairs{$both} }, [ $state1, $state2 ]; |
|||
} |
|||
} |
|||
for my $pair (keys %pairs) { |
|||
next if 2 > @{ $pairs{$pair} }; |
|||
for my $pair1 (@{ $pairs{$pair} }) { |
|||
for my $pair2 (@{ $pairs{$pair} }) { |
|||
next if 4 > uniq(@$pair1, @$pair2) |
|||
or $pair1->[0] lt $pair2->[0]; |
|||
say join ' = ', map { join ' + ', @$_ } $pair1, $pair2; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
my @states = ( 'Alabama', 'Alaska', 'Arizona', 'Arkansas', |
|||
'California', 'Colorado', 'Connecticut', 'Delaware', |
|||
'Florida', 'Georgia', 'Hawaii', |
|||
'Idaho', 'Illinois', 'Indiana', 'Iowa', |
|||
'Kansas', 'Kentucky', 'Louisiana', |
|||
'Maine', 'Maryland', 'Massachusetts', 'Michigan', |
|||
'Minnesota', 'Mississippi', 'Missouri', 'Montana', |
|||
'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', |
|||
'New Mexico', 'New York', 'North Carolina', 'North Dakota', |
|||
'Ohio', 'Oklahoma', 'Oregon', |
|||
'Pennsylvania', 'Rhode Island', |
|||
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', |
|||
'Utah', 'Vermont', 'Virginia', |
|||
'Washington', 'West Virginia', 'Wisconsin', 'Wyoming', |
|||
); |
|||
my @fictious = ( 'New Kory', 'Wen Kory', 'York New', 'Kory New', 'New Kory' ); |
|||
say scalar @states, ' states:'; |
|||
puzzle(@states); |
|||
say @states + @fictious, ' states:'; |
|||
puzzle(@states, @fictious);</syntaxhighlight> |
|||
=={{header|Phix}}== |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">states</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Alabama"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Alaska"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Arizona"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Arkansas"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"California"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Colorado"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Connecticut"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Delaware"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Florida"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Georgia"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Hawaii"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Idaho"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Illinois"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Indiana"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Iowa"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Kansas"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Kentucky"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Louisiana"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Maine"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Maryland"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Massachusetts"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Michigan"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Minnesota"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Mississippi"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Missouri"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Montana"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Nebraska"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Nevada"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"New Hampshire"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"New Jersey"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"New Mexico"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"New York"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"North Carolina"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"North Dakota"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Ohio"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Oklahoma"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Oregon"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Pennsylvania"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Rhode Island"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"South Carolina"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"South Dakota"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Tennessee"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Texas"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Utah"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Vermont"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Virginia"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #008000;">"Washington"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"West Virginia"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Wisconsin"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Wyoming"</span><span style="color: #0000FF;">},</span> |
|||
<span style="color: #000080;font-style:italic;">-- extras = {"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"}</span> |
|||
<span style="color: #000000;">extras</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Slender Dragon"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Abalamara"</span><span style="color: #0000FF;">}</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">no_dup</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">s</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;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[$]</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</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: #008080;">return</span> <span style="color: #000000;">s</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">no_dup</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- empty dict</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;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</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: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">key</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])))</span> |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">data</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">putd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,{{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">}})</span> |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">k</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;">data</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">i</span> <span style="color: #008080;">and</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">j</span> <span style="color: #008080;">and</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">i</span> <span style="color: #008080;">and</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">j</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #0000FF;">?{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"<==>"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</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;">putd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">data</span><span style="color: #0000FF;">),{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</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: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #000000;">states</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #0000FF;">?</span><span style="color: #008000;">"==="</span> |
|||
<span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #000000;">states</span><span style="color: #0000FF;">&</span><span style="color: #000000;">extras</span><span style="color: #0000FF;">)</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
{"North Dakota","South Carolina","<==>","North Carolina","South Dakota"} |
|||
"===" |
|||
{"Alabama","Arkansas","<==>","Abalamara","Kansas"} |
|||
{"North Dakota","South Carolina","<==>","North Carolina","South Dakota"} |
|||
{"Oregon","Rhode Island","<==>","Ohio","Slender Dragon"} |
|||
</pre> |
|||
=={{header|PicoLisp}}== |
|||
<syntaxhighlight lang="picolisp">(setq *States |
|||
(group |
|||
(mapcar '((Name) (cons (clip (sort (chop (lowc Name)))) Name)) |
|||
(quote |
|||
"Alabama" "Alaska" "Arizona" "Arkansas" |
|||
"California" "Colorado" "Connecticut" |
|||
"Delaware" |
|||
"Florida" "Georgia" "Hawaii" |
|||
"Idaho" "Illinois" "Indiana" "Iowa" |
|||
"Kansas" "Kentucky" "Louisiana" |
|||
"Maine" "Maryland" "Massachusetts" "Michigan" |
|||
"Minnesota" "Mississippi" "Missouri" "Montana" |
|||
"Nebraska" "Nevada" "New Hampshire" "New Jersey" |
|||
"New Mexico" "New York" "North Carolina" "North Dakota" |
|||
"Ohio" "Oklahoma" "Oregon" |
|||
"Pennsylvania" "Rhode Island" |
|||
"South Carolina" "South Dakota" "Tennessee" "Texas" |
|||
"Utah" "Vermont" "Virginia" |
|||
"Washington" "West Virginia" "Wisconsin" "Wyoming" |
|||
"New Kory" "Wen Kory" "York New" "Kory New" "New Kory" ) ) ) ) |
|||
(extract |
|||
'((P) |
|||
(when (cddr P) |
|||
(mapcar |
|||
'((X) |
|||
(cons |
|||
(cadr (assoc (car X) *States)) |
|||
(cadr (assoc (cdr X) *States)) ) ) |
|||
(cdr P) ) ) ) |
|||
(group |
|||
(mapcon |
|||
'((X) |
|||
(extract |
|||
'((Y) |
|||
(cons |
|||
(sort (conc (copy (caar X)) (copy (car Y)))) |
|||
(caar X) |
|||
(car Y) ) ) |
|||
(cdr X) ) ) |
|||
*States ) ) )</syntaxhighlight> |
|||
Output: |
|||
<pre>-> ((("North Carolina" . "South Dakota") ("North Dakota" . "South Carolina")))</pre> |
|||
=={{header|Prolog}}== |
|||
Works with SWI-Prolog. Use of Goedel numbers. |
|||
<syntaxhighlight lang="prolog">state_name_puzzle :- |
|||
L = ["Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", |
|||
"Delaware", |
|||
"Florida", "Georgia", "Hawaii", |
|||
"Idaho", "Illinois", "Indiana", "Iowa", |
|||
"Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", |
|||
"Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming", |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"], |
|||
maplist(goedel, L, R), |
|||
% sort remove duplicates |
|||
sort(R, RS), |
|||
study(RS). |
|||
study([]). |
|||
study([V-Word|T]) :- |
|||
study_1_Word(V-Word, T, T), |
|||
study(T). |
|||
study_1_Word(_, [], _). |
|||
study_1_Word(V1-W1, [V2-W2 | T1], T) :- |
|||
TT is V1+V2, |
|||
study_2_Word(W1, W2, TT, T), |
|||
study_1_Word(V1-W1, T1, T). |
|||
study_2_Word(_W1, _W2, _TT, []). |
|||
study_2_Word(W1, W2, TT, [V3-W3 | T]) :- |
|||
( W2 \= W3 -> study_3_Word(W1, W2, TT, V3-W3, T); true), |
|||
study_2_Word(W1, W2, TT, T). |
|||
study_3_Word(_W1, _W2, _TT, _V3-_W3, []). |
|||
study_3_Word(W1, W2, TT, V3-W3, [V4-W4|T]) :- |
|||
TT1 is V3 + V4, |
|||
( TT1 < TT -> study_3_Word(W1, W2, TT, V3-W3, T) |
|||
; (TT1 = TT -> ( W4 \= W2 -> format('~w & ~w with ~w & ~w~n', [W1, W2, W3, W4]) |
|||
; true), |
|||
study_3_Word(W1, W2, TT, V3-W3, T)) |
|||
; true). |
|||
% Compute a Goedel number for the word |
|||
goedel(Word, Goedel-A) :- |
|||
name(A, Word), |
|||
downcase_atom(A, Amin), |
|||
atom_codes(Amin, LA), |
|||
compute_Goedel(LA, 0, Goedel). |
|||
compute_Goedel([], G, G). |
|||
compute_Goedel([32|T], GC, GF) :- |
|||
compute_Goedel(T, GC, GF). |
|||
compute_Goedel([H|T], GC, GF) :- |
|||
Ind is H - 97, |
|||
GC1 is GC + 26 ** Ind, |
|||
compute_Goedel(T, GC1, GF). |
|||
</syntaxhighlight> |
|||
Output : |
|||
<pre> ?- time(state_name_puzzle). |
|||
North Carolina & South Dakota with North Dakota & South Carolina |
|||
Kory New & New Kory with New York & Wen Kory |
|||
Kory New & New Kory with New York & York New |
|||
Kory New & New Kory with Wen Kory & York New |
|||
Kory New & New York with New Kory & Wen Kory |
|||
Kory New & New York with New Kory & York New |
|||
Kory New & New York with Wen Kory & York New |
|||
Kory New & Wen Kory with New Kory & New York |
|||
Kory New & Wen Kory with New Kory & York New |
|||
Kory New & Wen Kory with New York & York New |
|||
Kory New & York New with New Kory & New York |
|||
Kory New & York New with New Kory & Wen Kory |
|||
Kory New & York New with New York & Wen Kory |
|||
New Kory & New York with Wen Kory & York New |
|||
New Kory & Wen Kory with New York & York New |
|||
New Kory & York New with New York & Wen Kory |
|||
% 1,076,511 inferences, 1.078 CPU in 1.141 seconds (94% CPU, 998503 Lips) |
|||
true . |
|||
</pre> |
|||
=={{header|Python}}== |
|||
{{trans|D}} |
|||
<syntaxhighlight lang="python">from collections import defaultdict |
|||
states = ["Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", "Delaware", "Florida", |
|||
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", |
|||
"Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", |
|||
"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", |
|||
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", |
|||
"Oregon", "Pennsylvania", "Rhode Island", "South Carolina", |
|||
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming", |
|||
# Uncomment the next line for the fake states. |
|||
# "New Kory", "Wen Kory", "York New", "Kory New", "New Kory" |
|||
] |
|||
states = sorted(set(states)) |
|||
smap = defaultdict(list) |
|||
for i, s1 in enumerate(states[:-1]): |
|||
for s2 in states[i + 1:]: |
|||
smap["".join(sorted(s1 + s2))].append(s1 + " + " + s2) |
|||
for pairs in sorted(smap.itervalues()): |
|||
if len(pairs) > 1: |
|||
print " = ".join(pairs)</syntaxhighlight> |
|||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(define states |
|||
(list->set |
|||
(map string-downcase |
|||
'("Alabama" "Alaska" "Arizona" "Arkansas" |
|||
"California" "Colorado" "Connecticut" |
|||
"Delaware" |
|||
"Florida" "Georgia" "Hawaii" |
|||
"Idaho" "Illinois" "Indiana" "Iowa" |
|||
"Kansas" "Kentucky" "Louisiana" |
|||
"Maine" "Maryland" "Massachusetts" "Michigan" |
|||
"Minnesota" "Mississippi" "Missouri" "Montana" |
|||
"Nebraska""Nevada" "New Hampshire" "New Jersey" |
|||
"New Mexico" "New York" "North Carolina" "North Dakota" |
|||
"Ohio" "Oklahoma" "Oregon" |
|||
"Pennsylvania" "Rhode Island" |
|||
"South Carolina" "South Dakota" "Tennessee" "Texas" |
|||
"Utah" "Vermont" "Virginia" |
|||
"Washington" "West Virginia" "Wisconsin" "Wyoming" |
|||
; "New Kory" "Wen Kory" "York New" "Kory New" "New Kory" |
|||
)))) |
|||
(define (canon s t) |
|||
(sort (append (string->list s) (string->list t)) char<? )) |
|||
(define seen (make-hash)) |
|||
(for* ([s1 states] [s2 states] #:when (string<? s1 s2)) |
|||
(define c (canon s1 s2)) |
|||
(cond [(hash-ref seen c (λ() (hash-set! seen c (list s1 s2)) #f)) |
|||
=> (λ(states) (displayln (~v states (list s1 s2))))])) |
|||
</syntaxhighlight> |
|||
Output: |
|||
<syntaxhighlight lang="racket"> |
|||
'("north dakota" "south carolina") '("north carolina" "south dakota") |
|||
</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{Works with|rakudo|2018.03}} |
|||
<syntaxhighlight lang="raku" line>my @states = < |
|||
Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware |
|||
Florida Georgia Hawaii Idaho Illinois Indiana Iowa Kansas Kentucky |
|||
Louisiana Maine Maryland Massachusetts Michigan Minnesota Mississippi |
|||
Missouri Montana Nebraska Nevada New_Hampshire New_Jersey New_Mexico |
|||
New_York North_Carolina North_Dakota Ohio Oklahoma Oregon Pennsylvania |
|||
Rhode_Island South_Carolina South_Dakota Tennessee Texas Utah Vermont |
|||
Virginia Washington West_Virginia Wisconsin Wyoming |
|||
>; |
|||
say "50 states:"; |
|||
.say for anastates @states; |
|||
say "\n54 states:"; |
|||
.say for sort anastates @states, < New_Kory Wen_Kory York_New Kory_New New_Kory >; |
|||
sub anastates (*@states) { |
|||
my @s = @states.unique».subst('_', ' '); |
|||
my @pairs = gather for ^@s -> $i { |
|||
for $i ^..^ @s -> $j { |
|||
take [ @s[$i], @s[$j] ]; |
|||
} |
|||
} |
|||
my $equivs = hash @pairs.classify: *.lc.comb.sort.join; |
|||
gather for $equivs.values -> @c { |
|||
for ^@c -> $i { |
|||
for $i ^..^ @c -> $j { |
|||
my $set = set @c[$i].list, @c[$j].list; |
|||
take @c[$i].list.join(', ') ~ ' = ' ~ @c[$j].list.join(', ') if $set == 4; |
|||
} |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>50 states: |
|||
North Carolina, South Dakota = North Dakota, South Carolina |
|||
54 states: |
|||
New Kory, Kory New = Wen Kory, York New |
|||
New Kory, Wen Kory = York New, Kory New |
|||
New Kory, York New = Wen Kory, Kory New |
|||
New York, Kory New = New Kory, Wen Kory |
|||
New York, Kory New = New Kory, York New |
|||
New York, Kory New = Wen Kory, York New |
|||
New York, New Kory = Wen Kory, Kory New |
|||
New York, New Kory = Wen Kory, York New |
|||
New York, New Kory = York New, Kory New |
|||
New York, Wen Kory = New Kory, Kory New |
|||
New York, Wen Kory = New Kory, York New |
|||
New York, Wen Kory = York New, Kory New |
|||
New York, York New = New Kory, Kory New |
|||
New York, York New = New Kory, Wen Kory |
|||
New York, York New = Wen Kory, Kory New |
|||
North Carolina, South Dakota = North Dakota, South Carolina</pre> |
|||
=={{header|REXX}}== |
|||
Code was added to the REXX program to remove dead-end words (state names) that can't possibly be part of |
|||
<br>a solution, in particular, words that contain a unique letter (among all the state names). |
|||
<syntaxhighlight lang="rexx">/*REXX program (state name puzzle) rearranges two state's names ──► two new states. */ |
|||
!='Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware, Florida, Georgia,', |
|||
'Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, ', |
|||
'Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, New Hampshire, New Jersey, New Mexico,', |
|||
'New York, North Carolina, North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,', |
|||
'South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia, Wisconsin, Wyoming' |
|||
parse arg xtra; !=! ',' xtra /*add optional (fictitious) names.*/ |
|||
@abcU= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; !=space(!) /*!: the state list, no extra blanks*/ |
|||
deads=0; dups=0; L.=0; !orig=!; @@.= /*initialize some REXX variables. */ |
|||
z=0 /* [↑] elide dend─end (DE) states.*/ |
|||
do de=0 for 2; !=!orig /*use original state list for each. */ |
|||
@.= |
|||
do states=0 by 0 until !=='' /*parse until the cows come home. */ |
|||
parse var ! x ',' !; x=space(x) /*remove all blanks from state name.*/ |
|||
if @.x\=='' then do /*was state was already specified? */ |
|||
if de then iterate /*don't tell error if doing 2nd pass*/ |
|||
dups=dups + 1 /*bump the duplicate counter. */ |
|||
say 'ignoring the 2nd naming of the state: ' x; iterate |
|||
end |
|||
@.x=x /*indicate this state name exists. */ |
|||
y=space(x,0); upper y; yLen=length(y) /*get upper name with no spaces; Len*/ |
|||
if de then do /*Is the firstt pass? Then process.*/ |
|||
do j=1 for yLen /*see if it's a dead─end state name.*/ |
|||
_=substr(y, j, 1) /* _: is some state name character.*/ |
|||
if L._ \== 1 then iterate /*Count ¬ 1? Then state name is OK.*/ |
|||
say 'removing dead─end state [which has the letter ' _"]: " x |
|||
deads=deads + 1 /*bump number of dead─ends states. */ |
|||
iterate states /*go and process another state name.*/ |
|||
end /*j*/ |
|||
z=z+1 /*bump counter of the state names. */ |
|||
#.z=y; ##.z=x /*assign state name; also original.*/ |
|||
end |
|||
else do k=1 for yLen /*inventorize letters of state name.*/ |
|||
_=substr(y,k,1); L._=L._ + 1 /*count each letter in state name. */ |
|||
end /*k*/ |
|||
end /*states*/ /*the index STATES isn't incremented*/ |
|||
end /*de*/ |
|||
call list /*list state names in order given. */ |
|||
say z 'state name's(z) "are useable." |
|||
if dups \==0 then say dups 'duplicate of a state's(dups) 'ignored.' |
|||
if deads\==0 then say deads 'dead─end state's(deads) 'deleted.' |
|||
sols=0 /*number of solutions found (so far)*/ |
|||
say /*[↑] look for mix and match states*/ |
|||
do j=1 for z /* ◄──────────────────────────────────────────────────────────┐ */ |
|||
do k=j+1 to z /* ◄─── state K, state J ►─────┘ */ |
|||
if #.j<<#.k then JK=#.j || #.k /*is the state in the proper order? */ |
|||
else JK=#.k || #.j /*No, then use the new state name. */ |
|||
do m=1 for z; if m==j | m==k then iterate /*no state overlaps are allowed. */ |
|||
if verify(#.m, jk) \== 0 then iterate /*is this state name even possible? */ |
|||
nJK=elider(JK, #.m) /*a new JK, after eliding #.m chars.*/ |
|||
do n=m+1 to z; if n==j | n==k then iterate /*no overlaps are allowed. */ |
|||
if verify(#.n, nJK) \== 0 then iterate /*is it possible? */ |
|||
if elider(nJK, #.n) \== '' then iterate /*any leftovers letters? */ |
|||
if #.m<<#.n then MN=#.m || #.n /*is it in the proper order?*/ |
|||
else MN=#.n || #.m /*we found a new state name.*/ |
|||
if @@.JK.MN\=='' | @@.MN.JK\=="" then iterate /*was it done before? */ |
|||
say 'found: ' ##.j',' ##.k " ───► " ##.m',' ##.n |
|||
@@.JK.MN=1 /*indicate this solution as being found*/ |
|||
sols=sols+1 /*bump the number of solutions found. */ |
|||
end /*n*/ |
|||
end /*m*/ |
|||
end /*k*/ |
|||
end /*j*/ |
|||
say /*show a blank line for easier reading.*/ |
|||
if sols==0 then sols= 'No' /*use mucher gooder (sic) Englishings. */ |
|||
say sols 'solution's(sols) "found." /*display the number of solutions found*/ |
|||
exit /*stick a fork in it, we're all done. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
elider: parse arg hay,pins /*remove letters (pins) from haystack. */ |
|||
do e=1 for length(pins); p=pos( substr( pins, e, 1), hay) |
|||
if p==0 then iterate ; hay=overlay(' ', hay, p) |
|||
end /*e*/ /* [↑] remove a letter from haystack. */ |
|||
return space(hay, 0) /*remove blanks from the haystack. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
list: say; do i=1 for z; say right(i, 9) ##.i; end; say; return |
|||
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*pluralizer.*/</syntaxhighlight> |
|||
{{out|output|text= when using the default input:}} |
|||
<pre style="height:60ex"> |
|||
removing dead─end state [which has the letter Z]: Arizona |
|||
removing dead─end state [which has the letter J]: New Jersey |
|||
1 Alabama |
|||
2 Alaska |
|||
3 Arkansas |
|||
4 California |
|||
5 Colorado |
|||
6 Connecticut |
|||
7 Delaware |
|||
8 Florida |
|||
9 Georgia |
|||
10 Hawaii |
|||
11 Idaho |
|||
12 Illinois |
|||
13 Indiana |
|||
14 Iowa |
|||
15 Kansas |
|||
16 Kentucky |
|||
17 Louisiana |
|||
18 Maine |
|||
19 Maryland |
|||
20 Massachusetts |
|||
21 Michigan |
|||
22 Minnesota |
|||
23 Mississippi |
|||
24 Missouri |
|||
25 Montana |
|||
26 Nebraska |
|||
27 Nevada |
|||
28 New Hampshire |
|||
29 New Mexico |
|||
30 New York |
|||
31 North Carolina |
|||
32 North Dakota |
|||
33 Ohio |
|||
34 Oklahoma |
|||
35 Oregon |
|||
36 Pennsylvania |
|||
37 Rhode Island |
|||
38 South Carolina |
|||
39 South Dakota |
|||
40 Tennessee |
|||
41 Texas |
|||
42 Utah |
|||
43 Vermont |
|||
44 Virginia |
|||
45 Washington |
|||
46 West Virginia |
|||
47 Wisconsin |
|||
48 Wyoming |
|||
48 state names are useable. |
|||
2 dead─end states deleted. |
|||
found: North Carolina, South Dakota ───► North Dakota, South Carolina |
|||
1 solution found. |
|||
</pre> |
|||
'''output''' when using the input of: <tt> New Kory, Wen Kory, York New, Kory New, New Kory </tt> |
|||
<pre style="height:60ex"> |
|||
ignoring the 2nd naming of the state: New Kory |
|||
removing dead─end state [which has the letter Z]: Arizona |
|||
removing dead─end state [which has the letter J]: New Jersey |
|||
1 Alabama |
|||
2 Alaska |
|||
3 Arkansas |
|||
4 California |
|||
5 Colorado |
|||
6 Connecticut |
|||
7 Delaware |
|||
8 Florida |
|||
9 Georgia |
|||
10 Hawaii |
|||
11 Idaho |
|||
12 Illinois |
|||
13 Indiana |
|||
14 Iowa |
|||
15 Kansas |
|||
16 Kentucky |
|||
17 Louisiana |
|||
18 Maine |
|||
19 Maryland |
|||
20 Massachusetts |
|||
21 Michigan |
|||
22 Minnesota |
|||
23 Mississippi |
|||
24 Missouri |
|||
25 Montana |
|||
26 Nebraska |
|||
27 Nevada |
|||
28 New Hampshire |
|||
29 New Mexico |
|||
30 New York |
|||
31 North Carolina |
|||
32 North Dakota |
|||
33 Ohio |
|||
34 Oklahoma |
|||
35 Oregon |
|||
36 Pennsylvania |
|||
37 Rhode Island |
|||
38 South Carolina |
|||
39 South Dakota |
|||
40 Tennessee |
|||
41 Texas |
|||
42 Utah |
|||
43 Vermont |
|||
44 Virginia |
|||
45 Washington |
|||
46 West Virginia |
|||
47 Wisconsin |
|||
48 Wyoming |
|||
49 New Kory |
|||
50 Wen Kory |
|||
51 York New |
|||
52 Kory New |
|||
52 state names are useable. |
|||
1 duplicate of a state ignored. |
|||
2 dead─end states deleted. |
|||
found: New York, New Kory ───► Wen Kory, York New |
|||
found: New York, New Kory ───► Wen Kory, Kory New |
|||
found: New York, New Kory ───► York New, Kory New |
|||
found: New York, Wen Kory ───► New Kory, York New |
|||
found: New York, Wen Kory ───► New Kory, Kory New |
|||
found: New York, Wen Kory ───► York New, Kory New |
|||
found: New York, York New ───► New Kory, Wen Kory |
|||
found: New York, York New ───► New Kory, Kory New |
|||
found: New York, York New ───► Wen Kory, Kory New |
|||
found: New York, Kory New ───► New Kory, Wen Kory |
|||
found: New York, Kory New ───► New Kory, York New |
|||
found: New York, Kory New ───► Wen Kory, York New |
|||
found: North Carolina, South Dakota ───► North Dakota, South Carolina |
|||
found: New Kory, Wen Kory ───► York New, Kory New |
|||
found: New Kory, York New ───► Wen Kory, Kory New |
|||
found: New Kory, Kory New ───► Wen Kory, York New |
|||
16 solutions found. |
|||
</pre> |
|||
=={{header|Ruby}}== |
|||
{{trans|Tcl}} |
|||
<syntaxhighlight lang="ruby">require 'set' |
|||
# 26 prime numbers |
|||
Primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, |
|||
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101] |
|||
States = [ |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", |
|||
"Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", |
|||
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", |
|||
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", |
|||
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", |
|||
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", |
|||
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
] |
|||
def print_answer(states) |
|||
# find goedel numbers for all pairs of states |
|||
goedel = lambda {|str| str.chars.map {|c| Primes[c.ord - 65]}.reduce(:*)} |
|||
pairs = Hash.new {|h,k| h[k] = Array.new} |
|||
map = states.uniq.map {|state| [state, goedel[state.upcase.delete("^A-Z")]]} |
|||
map.combination(2) {|(s1,g1), (s2,g2)| pairs[g1 * g2] << [s1, s2]} |
|||
# find pairs without duplicates |
|||
result = [] |
|||
pairs.values.select {|val| val.length > 1}.each do |list_of_pairs| |
|||
list_of_pairs.combination(2) do |pair1, pair2| |
|||
if Set[*pair1, *pair2].length == 4 |
|||
result << [pair1, pair2] |
|||
end |
|||
end |
|||
end |
|||
# output the results |
|||
result.each_with_index do |(pair1, pair2), i| |
|||
puts "%d\t%s\t%s" % [i+1, pair1.join(', '), pair2.join(', ')] |
|||
end |
|||
end |
|||
puts "real states only" |
|||
print_answer(States) |
|||
puts "" |
|||
puts "with fictional states" |
|||
print_answer(States + ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"])</syntaxhighlight> |
|||
outputs |
|||
<pre style="height: 40ex; overflow: scroll">real states only |
|||
1 North Carolina, South Dakota North Dakota, South Carolina |
|||
with fictional states |
|||
1 New York, New Kory Wen Kory, York New |
|||
2 New York, New Kory Wen Kory, Kory New |
|||
3 New York, New Kory York New, Kory New |
|||
4 New York, Wen Kory New Kory, York New |
|||
5 New York, Wen Kory New Kory, Kory New |
|||
6 New York, Wen Kory York New, Kory New |
|||
7 New York, York New New Kory, Wen Kory |
|||
8 New York, York New New Kory, Kory New |
|||
9 New York, York New Wen Kory, Kory New |
|||
10 New York, Kory New New Kory, Wen Kory |
|||
11 New York, Kory New New Kory, York New |
|||
12 New York, Kory New Wen Kory, York New |
|||
13 New Kory, Wen Kory York New, Kory New |
|||
14 New Kory, York New Wen Kory, Kory New |
|||
15 New Kory, Kory New Wen Kory, York New |
|||
16 North Carolina, South Dakota North Dakota, South Carolina</pre> |
|||
=={{header|Scala}}== |
|||
<syntaxhighlight lang="scala">object StateNamePuzzle extends App { |
|||
// Logic: |
|||
def disjointPairs(pairs: Seq[Set[String]]) = |
|||
for (a <- pairs; b <- pairs; if a.intersect(b).isEmpty) yield Set(a,b) |
|||
def anagramPairs(words: Seq[String]) = |
|||
(for (a <- words; b <- words; if a != b) yield Set(a, b)) // all pairs |
|||
.groupBy(_.mkString.toLowerCase.replaceAll("[^a-z]", "").sorted) // grouped anagram pairs |
|||
.values.map(disjointPairs).flatMap(_.distinct) // unique non-overlapping anagram pairs |
|||
// Test: |
|||
val states = List( |
|||
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory", |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", |
|||
"Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", |
|||
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", |
|||
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", |
|||
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", |
|||
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", |
|||
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
) |
|||
println(anagramPairs(states).map(_.map(_ mkString " + ") mkString " = ") mkString "\n") |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>New Kory + Wen Kory = York New + Kory New |
|||
New Kory + Wen Kory = York New + New York |
|||
New Kory + Wen Kory = Kory New + New York |
|||
New Kory + York New = Wen Kory + Kory New |
|||
New Kory + York New = Wen Kory + New York |
|||
New Kory + York New = Kory New + New York |
|||
New Kory + Kory New = Wen Kory + York New |
|||
New Kory + Kory New = Wen Kory + New York |
|||
New Kory + Kory New = York New + New York |
|||
New Kory + New York = Wen Kory + York New |
|||
New Kory + New York = Wen Kory + Kory New |
|||
New Kory + New York = York New + Kory New |
|||
Wen Kory + York New = Kory New + New York |
|||
Wen Kory + Kory New = York New + New York |
|||
Wen Kory + New York = York New + Kory New |
|||
North Carolina + South Dakota = North Dakota + South Carolina</pre> |
|||
=={{header|Tcl}}== |
|||
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
|||
# Gödel number generator |
|||
proc goedel s { |
|||
set primes { |
|||
2 3 5 7 11 13 17 19 23 29 31 37 41 |
|||
43 47 53 59 61 67 71 73 79 83 89 97 101 |
|||
} |
|||
set n 1 |
|||
foreach c [split [string toupper $s] ""] { |
|||
if {![string is alpha $c]} continue |
|||
set n [expr {$n * [lindex $primes [expr {[scan $c %c] - 65}]]}] |
|||
} |
|||
return $n |
|||
} |
|||
# Calculates the pairs of states |
|||
proc groupStates {stateList} { |
|||
set stateList [lsort -unique $stateList] |
|||
foreach state1 $stateList { |
|||
foreach state2 $stateList { |
|||
if {$state1 >= $state2} continue |
|||
dict lappend group [goedel $state1$state2] [list $state1 $state2] |
|||
} |
|||
} |
|||
foreach g [dict values $group] { |
|||
if {[llength $g] > 1} { |
|||
foreach p1 $g { |
|||
foreach p2 $g { |
|||
if {$p1 < $p2 && [unshared $p1 $p2]} { |
|||
lappend result [list $p1 $p2] |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return $result |
|||
} |
|||
proc unshared args { |
|||
foreach p $args { |
|||
foreach a $p {incr s($a)} |
|||
} |
|||
expr {[array size s] == [llength $args]*2} |
|||
} |
|||
# Pretty printer for state name pair lists |
|||
proc printPairs {title groups} { |
|||
foreach group $groups { |
|||
puts "$title Group #[incr count]" |
|||
foreach statePair $group { |
|||
puts "\t[join $statePair {, }]" |
|||
} |
|||
} |
|||
} |
|||
set realStates { |
|||
"Alabama" "Alaska" "Arizona" "Arkansas" "California" "Colorado" |
|||
"Connecticut" "Delaware" "Florida" "Georgia" "Hawaii" "Idaho" "Illinois" |
|||
"Indiana" "Iowa" "Kansas" "Kentucky" "Louisiana" "Maine" "Maryland" |
|||
"Massachusetts" "Michigan" "Minnesota" "Mississippi" "Missouri" "Montana" |
|||
"Nebraska" "Nevada" "New Hampshire" "New Jersey" "New Mexico" "New York" |
|||
"North Carolina" "North Dakota" "Ohio" "Oklahoma" "Oregon" "Pennsylvania" |
|||
"Rhode Island" "South Carolina" "South Dakota" "Tennessee" "Texas" "Utah" |
|||
"Vermont" "Virginia" "Washington" "West Virginia" "Wisconsin" "Wyoming" |
|||
} |
|||
printPairs "Real States" [groupStates $realStates] |
|||
set falseStates { |
|||
"New Kory" "Wen Kory" "York New" "Kory New" "New Kory" |
|||
} |
|||
printPairs "Real and False States" [groupStates [concat $realStates $falseStates]]</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
Real States Group #1 |
|||
North Carolina, South Dakota |
|||
North Dakota, South Carolina |
|||
Real and False States Group #1 |
|||
Kory New, New Kory |
|||
New York, Wen Kory |
|||
Real and False States Group #2 |
|||
Kory New, New Kory |
|||
New York, York New |
|||
Real and False States Group #3 |
|||
Kory New, New Kory |
|||
Wen Kory, York New |
|||
Real and False States Group #4 |
|||
Kory New, New York |
|||
New Kory, Wen Kory |
|||
Real and False States Group #5 |
|||
Kory New, New York |
|||
New Kory, York New |
|||
Real and False States Group #6 |
|||
Kory New, New York |
|||
Wen Kory, York New |
|||
Real and False States Group #7 |
|||
Kory New, Wen Kory |
|||
New Kory, New York |
|||
Real and False States Group #8 |
|||
Kory New, Wen Kory |
|||
New Kory, York New |
|||
Real and False States Group #9 |
|||
Kory New, Wen Kory |
|||
New York, York New |
|||
Real and False States Group #10 |
|||
Kory New, York New |
|||
New Kory, New York |
|||
Real and False States Group #11 |
|||
Kory New, York New |
|||
New Kory, Wen Kory |
|||
Real and False States Group #12 |
|||
Kory New, York New |
|||
New York, Wen Kory |
|||
Real and False States Group #13 |
|||
New Kory, New York |
|||
Wen Kory, York New |
|||
Real and False States Group #14 |
|||
New Kory, Wen Kory |
|||
New York, York New |
|||
Real and False States Group #15 |
|||
New Kory, York New |
|||
New York, Wen Kory |
|||
Real and False States Group #16 |
|||
North Carolina, South Dakota |
|||
North Dakota, South Carolina |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{trans|Kotlin}} |
|||
{{libheader|Wren-str}} |
|||
{{libheader|Wren-sort}} |
|||
{{libheader|Wren-fmt}} |
|||
<syntaxhighlight lang="wren">import "./str" for Str |
|||
import "./sort" for Sort |
|||
import "./fmt" for Fmt |
|||
var solve = Fn.new { |states| |
|||
var dict = {} |
|||
for (state in states) { |
|||
var key = Str.lower(state).replace(" ", "") |
|||
if (!dict[key]) dict[key] = state |
|||
} |
|||
var keys = dict.keys.toList |
|||
Sort.quick(keys) |
|||
var solutions = [] |
|||
var duplicates = [] |
|||
for (i in 0...keys.count) { |
|||
for (j in i+1...keys.count) { |
|||
var len = keys[i].count + keys[j].count |
|||
var chars = (keys[i] + keys[j]).toList |
|||
Sort.quick(chars) |
|||
var combined = chars.join() |
|||
for (k in 0...keys.count) { |
|||
for (l in k+1...keys.count) { |
|||
if (k != i && k != j && l != i && l != j) { |
|||
var len2 = keys[k].count + keys[l].count |
|||
if (len2 == len) { |
|||
var chars2 = (keys[k] + keys[l]).toList |
|||
Sort.quick(chars2) |
|||
var combined2 = chars2.join() |
|||
if (combined == combined2) { |
|||
var f1 = "%(dict[keys[i]]) + %(dict[keys[j]])" |
|||
var f2 = "%(dict[keys[k]]) + %(dict[keys[l]])" |
|||
var f3 = "%(f1) = %(f2)" |
|||
if (!duplicates.contains(f3)) { |
|||
solutions.add(f3) |
|||
var f4 = "%(f2) = %(f1)" |
|||
duplicates.add(f4) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Sort.quick(solutions) |
|||
var i = 0 |
|||
for (sol in solutions) { |
|||
Fmt.print("$2d $s", i + 1, sol) |
|||
i = i + 1 |
|||
} |
|||
} |
|||
var states = [ |
|||
"Alabama", "Alaska", "Arizona", "Arkansas", |
|||
"California", "Colorado", "Connecticut", |
|||
"Delaware", |
|||
"Florida", "Georgia", "Hawaii", |
|||
"Idaho", "Illinois", "Indiana", "Iowa", |
|||
"Kansas", "Kentucky", "Louisiana", |
|||
"Maine", "Maryland", "Massachusetts", "Michigan", |
|||
"Minnesota", "Mississippi", "Missouri", "Montana", |
|||
"Nebraska", "Nevada", "New Hampshire", "New Jersey", |
|||
"New Mexico", "New York", "North Carolina", "North Dakota", |
|||
"Ohio", "Oklahoma", "Oregon", |
|||
"Pennsylvania", "Rhode Island", |
|||
"South Carolina", "South Dakota", "Tennessee", "Texas", |
|||
"Utah", "Vermont", "Virginia", |
|||
"Washington", "West Virginia", "Wisconsin", "Wyoming" |
|||
] |
|||
System.print("Real states only:") |
|||
solve.call(states) |
|||
System.print() |
|||
var fictitious = [ "New Kory", "Wen Kory", "York New", "Kory New", "New Kory" ] |
|||
System.print("Real and fictitious states:") |
|||
solve.call(states + fictitious)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Real states only: |
|||
1 North Carolina + South Dakota = North Dakota + South Carolina |
|||
Real and fictitious states: |
|||
1 Kory New + New Kory = New York + Wen Kory |
|||
2 Kory New + New Kory = New York + York New |
|||
3 Kory New + New Kory = Wen Kory + York New |
|||
4 Kory New + New York = New Kory + Wen Kory |
|||
5 Kory New + New York = New Kory + York New |
|||
6 Kory New + New York = Wen Kory + York New |
|||
7 Kory New + Wen Kory = New Kory + New York |
|||
8 Kory New + Wen Kory = New Kory + York New |
|||
9 Kory New + Wen Kory = New York + York New |
|||
10 Kory New + York New = New Kory + New York |
|||
11 Kory New + York New = New Kory + Wen Kory |
|||
12 Kory New + York New = New York + Wen Kory |
|||
13 New Kory + New York = Wen Kory + York New |
|||
14 New Kory + Wen Kory = New York + York New |
|||
15 New Kory + York New = New York + Wen Kory |
|||
16 North Carolina + South Dakota = North Dakota + South Carolina |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="zkl">#<<< // here doc |
|||
states:=("Alabama, Alaska, Arizona, Arkansas, |
|||
California, Colorado, Connecticut, Delaware, Florida, |
|||
Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, |
|||
Kentucky, Louisiana, Maine, Maryland, Massachusetts, |
|||
Michigan, Minnesota, Mississippi, Missouri, Montana, |
|||
Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, |
|||
New York, North Carolina, North Dakota, Ohio, Oklahoma, |
|||
Oregon, Pennsylvania, Rhode Island, South Carolina, |
|||
South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, |
|||
Washington, West Virginia, Wisconsin, Wyoming" |
|||
/* Uncomment the next line for the fake states. */ |
|||
# ",New Kory, Wen Kory, York New, Kory New, New Kory" |
|||
#<<< |
|||
).split(",").apply("strip"); |
|||
smap:=Dictionary(); |
|||
Utils.Helpers.pickNFrom(2,states).apply2('wrap(ss){ // 1225 combinations |
|||
key:=(ss.concat()).toLower().sort()-" "; |
|||
smap[key]=smap.find(key,List()).append(ss.concat(" + ")); |
|||
}); |
|||
foreach pairs in (smap.values){ // 1224 keys |
|||
// pairs=Utils.Helpers.listUnique(pairs); // eliminate dups |
|||
if(pairs.len()>1) |
|||
println(pairs.concat(" = ")) }</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
North Carolina + South Dakota = North Dakota + South Carolina |
|||
</pre> |
|||
{{omit from|GUISS}} |
Latest revision as of 16:28, 9 February 2024
You are encouraged to solve this task according to the task description, using any language you may know.
Background
This task is inspired by Mark Nelson's DDJ Column "Wordplay" and one of the weekly puzzle challenges from Will Shortz on NPR Weekend Edition [1] and originally attributed to David Edelheit.
The challenge was to take the names of two U.S. States, mix them all together, then rearrange the letters to form the names of two different U.S. States (so that all four state names differ from one another).
What states are these?
The problem was reissued on the Unicon Discussion Web which includes several solutions with analysis. Several techniques may be helpful and you may wish to refer to Gödel numbering, equivalence relations, and equivalence classes. The basic merits of these were discussed in the Unicon Discussion Web.
A second challenge in the form of a set of fictitious new states was also presented.
- Task
Write a program to solve the challenge using both the original list of states and the fictitious list.
- Caveats
- case and spacing aren't significant - just letters (harmonize case)
- don't expect the names to be in any order - such as being sorted
- don't rely on names to be unique (eliminate duplicates - meaning if Iowa appears twice you can only use it once)
Comma separated list of state names used in the original puzzle:
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"
Comma separated list of additional fictitious state names to be added to the original (Includes a duplicate):
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contains most consonants
- Find words which contains more than 3 vowels
- Find words which first and last three letters are equals
- Find words which odd letters are consonants and even letters are vowels or vice_versa
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 Bottles of Beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
11l
V states = [‘Alabama’, ‘Alaska’, ‘Arizona’, ‘Arkansas’,
‘California’, ‘Colorado’, ‘Connecticut’, ‘Delaware’, ‘Florida’,
‘Georgia’, ‘Hawaii’, ‘Idaho’, ‘Illinois’, ‘Indiana’, ‘Iowa’, ‘Kansas’,
‘Kentucky’, ‘Louisiana’, ‘Maine’, ‘Maryland’, ‘Massachusetts’,
‘Michigan’, ‘Minnesota’, ‘Mississippi’, ‘Missouri’, ‘Montana’,
‘Nebraska’, ‘Nevada’, ‘New Hampshire’, ‘New Jersey’, ‘New Mexico’,
‘New York’, ‘North Carolina’, ‘North Dakota’, ‘Ohio’, ‘Oklahoma’,
‘Oregon’, ‘Pennsylvania’, ‘Rhode Island’, ‘South Carolina’,
‘South Dakota’, ‘Tennessee’, ‘Texas’, ‘Utah’, ‘Vermont’, ‘Virginia’,
‘Washington’, ‘West Virginia’, ‘Wisconsin’, ‘Wyoming’]
states = sorted(states)
DefaultDict[String, [String]] smap
L(s1) states[0 .< (len)-1]
V i = L.index
L(s2) states[i+1..]
smap[sorted(s1‘’s2)].append(s1‘ + ’s2)
L(pairs) sorted(smap.values())
I pairs.len > 1
print(pairs.join(‘ = ’))
- Output:
North Carolina + South Dakota = North Dakota + South Carolina
AppleScript
use AppleScript version "2.3.1" -- Mac OS X 10.9 (Mavericks) or later.
use sorter : script ¬
"Custom Iterative Ternary Merge Sort" -- <www.macscripter.net/t/timsort-and-nigsort/71383/3>
on stateNamePuzzle()
script o
property stateNames : {"Alabama", "Alaska", "Arizona", "Arkansas", ¬
"California", "Colorado", "Connecticut", "Delaware", ¬
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois", ¬
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", ¬
"Maine", "Maryland", "Massachusetts", "Michigan", ¬
"Minnesota", "Mississippi", "Missouri", "Montana", ¬
"Nebraska", "Nevada", "New Hampshire", "New Jersey", ¬
"New Mexico", "New York", "North Carolina", "North Dakota", ¬
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", ¬
"South Carolina", "South Dakota", "Tennessee", "Texas", ¬
"Utah", "Vermont", "Virginia", ¬
"Washington", "West Virginia", "Wisconsin", "Wyoming", ¬
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"}
property workList : {}
-- Custom comparison handler for the sort.
on isGreater(a, b)
return (beginning of a > beginning of b)
end isGreater
end script
ignoring case
-- Remove duplicates.
repeat with i from 1 to (count o's stateNames)
set thisName to o's stateNames's item i
if ({thisName} is not in o's workList) then set end of o's workList to thisName
end repeat
set o's stateNames to o's workList
-- Build a list of lists containing unique pairs of names preceded by
-- text composed of their combined and sorted visible characters.
set o's workList to {}
set stateCount to (count o's stateNames)
repeat with i from 1 to (stateCount - 1)
set name1 to o's stateNames's item i
repeat with j from (i + 1) to stateCount
set name2 to o's stateNames's item j
set chrs to (name1 & name2)'s characters
tell sorter to sort(chrs, 1, -1, {})
set end of o's workList to {join(chrs, "")'s word 1, {name1, name2}}
end repeat
end repeat
-- Sort the lists on the character strings
set pairCount to (count o's workList)
tell sorter to sort(o's workList, 1, pairCount, {comparer:o})
-- Look for groups of equal character strings and match
-- associated name pairs not containing the same name(s).
set output to {}
set l to 1
repeat while (l < pairCount)
set chrs to beginning of o's workList's item l
set r to l
repeat while ((r < pairCount) and (beginning of o's workList's item (r + 1) = chrs))
set r to r + 1
end repeat
if (r > l) then
repeat with i from l to (r - 1)
set {name1, name2} to end of o's workList's item i
set text1 to join(result, " and ") & " --> "
repeat with j from (i + 1) to r
set pair2 to end of o's workList's item j
if (not (({name1} is in pair2) or ({name2} is in pair2))) then
set end of output to text1 & join(pair2, " and ")
end if
end repeat
end repeat
end if
set l to r + 1
end repeat
end ignoring
return join(output, linefeed)
end stateNamePuzzle
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
stateNamePuzzle()
- Output:
"North Carolina and South Dakota --> North Dakota and South Carolina
New York and New Kory --> Wen Kory and York New
New York and New Kory --> Wen Kory and Kory New
New York and New Kory --> York New and Kory New
New York and Wen Kory --> New Kory and York New
New York and Wen Kory --> New Kory and Kory New
New York and Wen Kory --> York New and Kory New
New York and York New --> New Kory and Wen Kory
New York and York New --> New Kory and Kory New
New York and York New --> Wen Kory and Kory New
New York and Kory New --> New Kory and Wen Kory
New York and Kory New --> New Kory and York New
New York and Kory New --> Wen Kory and York New
New Kory and Wen Kory --> York New and Kory New
New Kory and York New --> Wen Kory and Kory New
New Kory and Kory New --> Wen Kory and York New"
Bracmat
( Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
Nebraska
Nevada
"New Hampshire"
"New Jersey"
"New Mexico"
"New York"
"North Carolina"
"North Dakota"
Ohio
Oklahoma
Oregon
Pennsylvania
"Rhode Island"
"South Carolina"
"South Dakota"
Tennessee
Texas
Utah
Vermont
Virginia
Washington
"West Virginia"
Wisconsin
Wyoming
: ?states
& "New Kory" "Wen Kory" "York New" "Kory New" "New Kory":?extrastates
& ( "State name puzzle"
= allStates State state statechars char
, A Z S1 S2 S3 S4 L1 L2 L3 L4 L12
. 0:?allStates
& whl
' ( !arg:%?State ?arg
& low$!State:?state
& 0:?statechars
& whl
' ( @(!state:? (%@:~" ":?char) ?state)
& !char+!statechars:?statechars
)
& (!State.!statechars)+!allStates:?allStates
)
& ( !allStates
: ?
+ ?*(?S1.?L1)
+ ?A
+ ?*(?S2.?L2)
+ ( ?Z
& !L1+!L2:?L12
& !A+!Z
: ?
+ ?*(?S3.?L3&!L12+-1*!L3:?L4)
+ ?
+ ?
* ( ?S4
. !L4
& out$(!S1 "+" !S2 "=" !S3 "+" !S4)
& ~
)
+ ?
)
| out$"No more solutions"
)
)
& "State name puzzle"$!states
& "State name puzzle"$(!states !extrastates)
);
Output:
North Carolina + South Dakota = North Dakota + South Carolina No more solutions Kory New + New Kory = New York + Wen Kory Kory New + New Kory = New York + York New Kory New + New Kory = Wen Kory + York New Kory New + New York = New Kory + Wen Kory Kory New + New York = New Kory + York New Kory New + New York = Wen Kory + York New Kory New + Wen Kory = New Kory + New York Kory New + Wen Kory = New Kory + York New Kory New + Wen Kory = New York + York New Kory New + York New = New Kory + New York Kory New + York New = New Kory + Wen Kory Kory New + York New = New York + Wen Kory New Kory + New York = Wen Kory + York New New Kory + Wen Kory = New York + York New New Kory + York New = New York + Wen Kory North Carolina + South Dakota = North Dakota + South Carolina No more solutions
C
Sort by letter occurence and deal with dupes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define USE_FAKES 1
const char *states[] = {
#if USE_FAKES
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory",
#endif
"Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut",
"Delaware",
"Florida", "Georgia", "Hawaii",
"Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
};
int n_states = sizeof(states)/sizeof(*states);
typedef struct { unsigned char c[26]; const char *name[2]; } letters;
void count_letters(letters *l, const char *s)
{
int c;
if (!l->name[0]) l->name[0] = s;
else l->name[1] = s;
while ((c = *s++)) {
if (c >= 'a' && c <= 'z') l->c[c - 'a']++;
if (c >= 'A' && c <= 'Z') l->c[c - 'A']++;
}
}
int lcmp(const void *aa, const void *bb)
{
int i;
const letters *a = aa, *b = bb;
for (i = 0; i < 26; i++)
if (a->c[i] > b->c[i]) return 1;
else if (a->c[i] < b->c[i]) return -1;
return 0;
}
int scmp(const void *a, const void *b)
{
return strcmp(*(const char *const *)a, *(const char *const *)b);
}
void no_dup()
{
int i, j;
qsort(states, n_states, sizeof(const char*), scmp);
for (i = j = 0; i < n_states;) {
while (++i < n_states && !strcmp(states[i], states[j]));
if (i < n_states) states[++j] = states[i];
}
n_states = j + 1;
}
void find_mix()
{
int i, j, n;
letters *l, *p;
no_dup();
n = n_states * (n_states - 1) / 2;
p = l = calloc(n, sizeof(letters));
for (i = 0; i < n_states; i++)
for (j = i + 1; j < n_states; j++, p++) {
count_letters(p, states[i]);
count_letters(p, states[j]);
}
qsort(l, n, sizeof(letters), lcmp);
for (j = 0; j < n; j++) {
for (i = j + 1; i < n && !lcmp(l + j, l + i); i++) {
if (l[j].name[0] == l[i].name[0]
|| l[j].name[1] == l[i].name[0]
|| l[j].name[1] == l[i].name[1])
continue;
printf("%s + %s => %s + %s\n",
l[j].name[0], l[j].name[1], l[i].name[0], l[i].name[1]);
}
}
free(l);
}
int main(void)
{
find_mix();
return 0;
}
C++
Ported from C solution.
#include <algorithm>
#include <iostream>
#include <string>
#include <array>
#include <vector>
template<typename T>
T unique(T&& src)
{
T retval(std::move(src));
std::sort(retval.begin(), retval.end(), std::less<typename T::value_type>());
retval.erase(std::unique(retval.begin(), retval.end()), retval.end());
return retval;
}
#define USE_FAKES 1
auto states = unique(std::vector<std::string>({
#if USE_FAKES
"Slender Dragon", "Abalamara",
#endif
"Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut",
"Delaware",
"Florida", "Georgia", "Hawaii",
"Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
}));
struct counted_pair
{
std::string name;
std::array<int, 26> count{};
void count_characters(const std::string& s)
{
for (auto&& c : s) {
if (c >= 'a' && c <= 'z') count[c - 'a']++;
if (c >= 'A' && c <= 'Z') count[c - 'A']++;
}
}
counted_pair(const std::string& s1, const std::string& s2)
: name(s1 + " + " + s2)
{
count_characters(s1);
count_characters(s2);
}
};
bool operator<(const counted_pair& lhs, const counted_pair& rhs)
{
auto lhs_size = lhs.name.size();
auto rhs_size = rhs.name.size();
return lhs_size == rhs_size
? std::lexicographical_compare(lhs.count.begin(),
lhs.count.end(),
rhs.count.begin(),
rhs.count.end())
: lhs_size < rhs_size;
}
bool operator==(const counted_pair& lhs, const counted_pair& rhs)
{
return lhs.name.size() == rhs.name.size() && lhs.count == rhs.count;
}
int main()
{
const int n_states = states.size();
std::vector<counted_pair> pairs;
for (int i = 0; i < n_states; i++) {
for (int j = 0; j < i; j++) {
pairs.emplace_back(counted_pair(states[i], states[j]));
}
}
std::sort(pairs.begin(), pairs.end());
auto start = pairs.begin();
while (true) {
auto match = std::adjacent_find(start, pairs.end());
if (match == pairs.end()) {
break;
}
auto next = match + 1;
std::cout << match->name << " => " << next->name << "\n";
start = next;
}
}
Clojure
(ns clojure-sandbox.statenames
(:require [clojure.data.csv :as csv]
[clojure.java.io :as io]
[clojure.string :refer [lower-case]]
[clojure.math.combinatorics :as c]
[clojure.pprint :as pprint]))
(def made-up-states ["New Kory" "Wen Kory" "York New" "Kory New" "New Kory"])
;; I saved the list of states in a local file to keep the code clean but you can copy and paste the list instead
(def real-states (with-open [in-file (io/reader (io/resource "states.csv"))]
(->> (doall
(csv/read-csv in-file))
(map first))))
(defn- state->charset [state-name]
"Convert state name into sorted list of characters with no spaces"
(->> state-name
char-array
sort
(filter (set (map char (range 97 123)))))) ;; ASCII range for lower case letters
(defn- add-charsets [states]
"Calculate sorted character list for each state and store with name"
(->> states
(map lower-case) ;; Convert all names to lower case
set ;; remove duplicates
(map
(fn [s] {:name s
:characters (state->charset s)})))) ;; add characters
(defn- pair-chars [state1 state2]
"Join the characters of two states together and sort them"
(-> state1
:characters
(concat (:characters state2))
sort))
(defn- pair [[state1 state2]]
"Record representing two state names and the total characters used in them"
{:inputs [(:name state1) (:name state2)]
:characters (pair-chars state1 state2)})
(defn- find-all-pairs [elements]
(c/combinations elements 2))
(defn- pairs-to-search [state-names]
"Create character lists for all states and return a list of all possible pairs"
(->> state-names
add-charsets
find-all-pairs
(map pair)))
(defn- pairs-have-same-letters? [[pair1 pair2]]
(= (:characters pair1) (:characters pair2)))
(defn- inputs-are-distinct? [[pair1 pair2 :as pairs]]
"Check that two pairs of states don't contain the same state"
(= 4 ;; There should be a total of 4 distinct states in the two pairs
(->> pairs
(map :inputs)
flatten
set
count)))
(defn- search [pairs]
(->> pairs
find-all-pairs ;; find pairs of pairs to search
(filter pairs-have-same-letters?) ;; Keep only those where each pair has the same characters
(filter inputs-are-distinct?))) ;; Remove pairs with duplicate states
(defn find-matches [state-names]
"Find all state pairs and return pairs of them using the same letters"
(-> state-names
pairs-to-search
search))
(defn- format-match-output [[pair1 pair2]]
"Format a pair of state pairs to print out"
(str (first (:inputs pair1))
" + "
(last (:inputs pair1))
" = "
(first (:inputs pair2))
" + "
(last (:inputs pair2))))
(defn- evaluate-and-print [states]
(->> states
find-matches
(map format-match-output)
pprint/pprint))
(defn -main [& args]
(println "Solutions for 50 real states")
(evaluate-and-print real-states)
(println "Solutions with made up states added")
(evaluate-and-print (concat real-states made-up-states)))
- Output:
Solutions for 50 real states ("north carolina + south dakota = south carolina + north dakota") Solutions with made up states added ("new york + new kory = kory new + york new" "new york + new kory = kory new + wen kory" "new york + new kory = york new + wen kory" "new york + kory new = new kory + york new" "new york + kory new = new kory + wen kory" "new york + kory new = york new + wen kory" "new york + york new = new kory + kory new" "new york + york new = new kory + wen kory" "new york + york new = kory new + wen kory" "new york + wen kory = new kory + kory new" "new york + wen kory = new kory + york new" "new york + wen kory = kory new + york new" "north carolina + south dakota = south carolina + north dakota" "new kory + kory new = york new + wen kory" "new kory + york new = kory new + wen kory" "new kory + wen kory = kory new + york new")
D
import std.stdio, std.algorithm, std.string, std.exception;
auto states = ["Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas",
"Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma",
"Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming",
// Uncomment the next line for the fake states.
// "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"
];
void main() {
states.length -= states.sort().uniq.copy(states).length;
string[][const ubyte[]] smap;
foreach (immutable i, s1; states[0 .. $ - 1])
foreach (s2; states[i + 1 .. $])
smap[(s1 ~ s2).dup.representation.sort().release.assumeUnique]
~= s1 ~ " + " ~ s2;
writefln("%-(%-(%s = %)\n%)",
smap.values.sort().filter!q{ a.length > 1 });
}
- Output:
North Carolina + South Dakota = North Dakota + South Carolina
F#
// State name puzzle. Nigel Galloway: February 9th., 2023
let states=["Alabama"; "Alaska"; "Arizona"; "Arkansas"; "California"; "Colorado"; "Connecticut"; "Delaware"; "Florida"; "Georgia"; "Hawaii"; "Idaho"; "Illinois"; "Indiana"; "Iowa"; "Kansas"; "Kentucky"; "Louisiana"; "Maine"; "Maryland"; "Massachusetts"; "Michigan"; "Minnesota"; "Mississippi"; "Missouri"; "Montana"; "Nebraska"; "Nevada"; "New Hampshire"; "New Jersey"; "New Mexico"; "New York"; "North Carolina"; "North Dakota"; "Ohio"; "Oklahoma"; "Oregon"; "Pennsylvania"; "Rhode Island"; "South Carolina"; "South Dakota"; "Tennessee"; "Texas"; "Utah"; "Vermont"; "Virginia"; "Washington"; "West Virginia"; "Wisconsin"; "Wyoming"; "New Kory"; "Wen Kory"; "York New"; "Kory New"; "New Kory"]|>List.distinct
let fN(i,g)(e,l)=let n=Array.zeroCreate<int>256
let fN i g=n[g]<-n[g]+i
let fG n g=(g:string).ToLower().ToCharArray()|>Array.iter(fun g->fN n (int g))
fG 1 i; fG 1 g; fG -1 e; fG -1 l; n|>Array.forall((=)0)
let n=states|>List.allPairs states|>List.filter(fun(n,g)->n<g)|>List.groupBy(fun(n,g)->n.Length+g.Length)
let g=n|>List.map(fun(_,n)->n|>List.allPairs n|>List.filter(fun((n,g),(n',g'))->(n,g)<(n',g') && n<>n' && n<>g' && g<>n' && g<>g' && fN(n,g)(n',g')))|>List.filter(List.isEmpty>>not)
g|>List.iter(List.iter(fun((i,g),(e,l))->printfn $"%s{i},%s{g}->%s{e},%s{l}"))
- Output:
New Kory,New York->Wen Kory,York New New Kory,Wen Kory->New York,York New New Kory,York New->New York,Wen Kory Kory New,New York->New Kory,Wen Kory Kory New,New York->New Kory,York New Kory New,New York->Wen Kory,York New Kory New,New Kory->New York,Wen Kory Kory New,New Kory->New York,York New Kory New,New Kory->Wen Kory,York New Kory New,Wen Kory->New York,York New Kory New,Wen Kory->New Kory,New York Kory New,Wen Kory->New Kory,York New Kory New,York New->New York,Wen Kory Kory New,York New->New Kory,New York Kory New,York New->New Kory,Wen Kory North Carolina,South Dakota->North Dakota,South Carolina
Go
package main
import (
"fmt"
"unicode"
)
var states = []string{"Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut",
"Delaware",
"Florida", "Georgia", "Hawaii",
"Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"}
func main() {
play(states)
play(append(states,
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"))
}
func play(states []string) {
fmt.Println(len(states), "states:")
// get list of unique state names
set := make(map[string]bool, len(states))
for _, s := range states {
set[s] = true
}
// make parallel arrays for unique state names and letter histograms
s := make([]string, len(set))
h := make([][26]byte, len(set))
var i int
for us := range set {
s[i] = us
for _, c := range us {
if u := uint(unicode.ToLower(c)) - 'a'; u < 26 {
h[i][u]++
}
}
i++
}
// use map to find matches. map key is sum of histograms of
// two different states. map value is indexes of the two states.
type pair struct {
i1, i2 int
}
m := make(map[string][]pair)
b := make([]byte, 26) // buffer for summing histograms
for i1, h1 := range h {
for i2 := i1 + 1; i2 < len(h); i2++ {
// sum histograms
for i := range b {
b[i] = h1[i] + h[i2][i]
}
k := string(b) // make key from buffer.
// now loop over any existing pairs with the same key,
// printing any where both states of this pair are different
// than the states of the existing pair
for _, x := range m[k] {
if i1 != x.i1 && i1 != x.i2 && i2 != x.i1 && i2 != x.i2 {
fmt.Printf("%s, %s = %s, %s\n", s[i1], s[i2],
s[x.i1], s[x.i2])
}
}
// store this pair in the map whether printed or not.
m[k] = append(m[k], pair{i1, i2})
}
}
}
Output:
50 states: North Dakota, South Carolina = North Carolina, South Dakota 55 states: South Dakota, North Carolina = North Dakota, South Carolina New Kory, Kory New = Wen Kory, York New New Kory, Kory New = Wen Kory, New York New Kory, York New = Wen Kory, Kory New New Kory, York New = Wen Kory, New York New Kory, New York = Wen Kory, Kory New New Kory, New York = Wen Kory, York New Kory New, York New = Wen Kory, New Kory Kory New, York New = Wen Kory, New York Kory New, York New = New Kory, New York Kory New, New York = Wen Kory, New Kory Kory New, New York = Wen Kory, York New Kory New, New York = New Kory, York New York New, New York = Wen Kory, New Kory York New, New York = Wen Kory, Kory New York New, New York = New Kory, Kory New
Haskell
{-# LANGUAGE TupleSections #-}
import Data.Char (isLetter, toLower)
import Data.Function (on)
import Data.List (groupBy, nub, sort, sortBy)
-------------------- STATE NAME PUZZLE -------------------
puzzle :: [String] -> [((String, String), (String, String))]
puzzle states =
concatMap
((filter isValid . pairs) . map snd)
( filter ((> 1) . length) $
groupBy ((==) `on` fst) $
sortBy
(compare `on` fst)
[ (pkey (a <> b), (a, b))
| (a, b) <- pairs (nub $ sort states)
]
)
where
pkey = sort . filter isLetter . map toLower
isValid ((a0, a1), (b0, b1)) =
(a0 /= b0)
&& (a0 /= b1)
&& (a1 /= b0)
&& (a1 /= b1)
pairs :: [a] -> [(a, a)]
pairs [] = []
pairs (y : ys) = map (y,) ys <> pairs ys
--------------------------- TEST -------------------------
main :: IO ()
main = do
putStrLn $
"Matching pairs generated from "
<> show (length stateNames)
<> " state names and "
<> show (length fakeStateNames)
<> " fake state names:"
mapM_ print $ puzzle $ stateNames <> fakeStateNames
stateNames :: [String]
stateNames =
[ "Alabama",
"Alaska",
"Arizona",
"Arkansas",
"California",
"Colorado",
"Connecticut",
"Delaware",
"Florida",
"Georgia",
"Hawaii",
"Idaho",
"Illinois",
"Indiana",
"Iowa",
"Kansas",
"Kentucky",
"Louisiana",
"Maine",
"Maryland",
"Massachusetts",
"Michigan",
"Minnesota",
"Mississippi",
"Missouri",
"Montana",
"Nebraska",
"Nevada",
"New Hampshire",
"New Jersey",
"New Mexico",
"New York",
"North Carolina",
"North Dakota",
"Ohio",
"Oklahoma",
"Oregon",
"Pennsylvania",
"Rhode Island",
"South Carolina",
"South Dakota",
"Tennessee",
"Texas",
"Utah",
"Vermont",
"Virginia",
"Washington",
"West Virginia",
"Wisconsin",
"Wyoming"
]
fakeStateNames :: [String]
fakeStateNames =
[ "New Kory",
"Wen Kory",
"York New",
"Kory New",
"New Kory"
]
- Output:
Matching pairs generated from 50 state names and 5 fake state names: (("North Carolina","South Dakota"),("North Dakota","South Carolina")) (("Kory New","New Kory"),("New York","Wen Kory")) (("Kory New","New Kory"),("New York","York New")) (("Kory New","New Kory"),("Wen Kory","York New")) (("Kory New","New York"),("New Kory","Wen Kory")) (("Kory New","New York"),("New Kory","York New")) (("Kory New","New York"),("Wen Kory","York New")) (("Kory New","Wen Kory"),("New Kory","New York")) (("Kory New","Wen Kory"),("New Kory","York New")) (("Kory New","Wen Kory"),("New York","York New")) (("Kory New","York New"),("New Kory","New York")) (("Kory New","York New"),("New Kory","Wen Kory")) (("Kory New","York New"),("New York","Wen Kory")) (("New Kory","New York"),("Wen Kory","York New")) (("New Kory","Wen Kory"),("New York","York New")) (("New Kory","York New"),("New York","Wen Kory"))
Icon and Unicon
Equivalence Class Solution
The following are common routines:
Godel Number Solution
strings.icn provides deletec, csort factors.icn provides prime
Sample Output (ECsolve):
northcarolina southdakota northdakota southcarolina ... runtime 0.019 2 matches found. wenkory yorknew wenkory newyork newyork yorknew wenkory korynew newyork korynew newkory korynew korynew yorknew wenkory newkory newkory newyork newkory yorknew northcarolina southdakota northdakota southcarolina ... runtime 0.026 12 matches found.
Sample Output (GNsolve):
north dakota:south carolina and north carolina:south dakota Time: 0.008999999999999999 north dakota:south carolina and north carolina:south dakota new kory:wen kory and new york:york new new kory:wen kory and kory new:new york new kory:york new and new york:wen kory new kory:york new and kory new:new york kory new:new kory and new york:wen kory kory new:new kory and new york:york new wen kory:york new and kory new:new york wen kory:york new and kory new:new kory wen kory:york new and new kory:new york kory new:wen kory and new york:york new kory new:wen kory and new kory:york new kory new:wen kory and new kory:new york kory new:york new and new york:wen kory kory new:york new and new kory:wen kory kory new:york new and new kory:new york Time: 0.018
J
Implementation:
require'strings stats'
states=:<;._2]0 :0-.LF
Alabama,Alaska,Arizona,Arkansas,California,Colorado,
Connecticut,Delaware,Florida,Georgia,Hawaii,Idaho,
Illinois,Indiana,Iowa,Kansas,Kentucky,Louisiana,
Maine,Maryland,Massachusetts,Michigan,Minnesota,
Mississippi,Missouri,Montana,Nebraska,Nevada,
New Hampshire,New Jersey,New Mexico,New York,
North Carolina,North Dakota,Ohio,Oklahoma,Oregon,
Pennsylvania,Rhode Island,South Carolina,
South Dakota,Tennessee,Texas,Utah,Vermont,Virginia,
Washington,West Virginia,Wisconsin,Wyoming,
Maine,Maine,Maine,Maine,Maine,Maine,Maine,Maine,
)
pairUp=: (#~ matchUp)@({~ 2 comb #)@~.
matchUp=: (i.~ ~: i:~)@:(<@normalize@;"1)
normalize=: /:~@tolower@-.&' '
In action:
pairUp states
┌──────────────┬──────────────┐
│North Carolina│South Dakota │
├──────────────┼──────────────┤
│North Dakota │South Carolina│
└──────────────┴──────────────┘
Note: this approach is sufficient to solve the original problem, but does not properly deal with the addition of fictitious states. So:
isolatePairs=: ~.@matchUp2@(#~ *./@matchUp"2)@({~ 2 comb #)
matchUp2=: /:~"2@:(/:~"1)@(#~ 4=#@~.@,"2)
In action:
isolatePairs pairUp 'New Kory';'Wen Kory';'York New';'Kory New';'New Kory';states
┌──────────────┬──────────────┐
│Kory New │York New │
├──────────────┼──────────────┤
│New Kory │Wen Kory │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│New Kory │Wen Kory │
├──────────────┼──────────────┤
│New York │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │New York │
├──────────────┼──────────────┤
│New Kory │Wen Kory │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │Wen Kory │
├──────────────┼──────────────┤
│New Kory │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│New Kory │York New │
├──────────────┼──────────────┤
│New York │Wen Kory │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │New York │
├──────────────┼──────────────┤
│New Kory │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │New Kory │
├──────────────┼──────────────┤
│Wen Kory │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │New Kory │
├──────────────┼──────────────┤
│New York │Wen Kory │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │New Kory │
├──────────────┼──────────────┤
│New York │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│New Kory │New York │
├──────────────┼──────────────┤
│Wen Kory │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │Wen Kory │
├──────────────┼──────────────┤
│New Kory │New York │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │York New │
├──────────────┼──────────────┤
│New Kory │New York │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │New York │
├──────────────┼──────────────┤
│Wen Kory │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │Wen Kory │
├──────────────┼──────────────┤
│New York │York New │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│Kory New │York New │
├──────────────┼──────────────┤
│New York │Wen Kory │
└──────────────┴──────────────┘
┌──────────────┬──────────────┐
│North Carolina│South Dakota │
├──────────────┼──────────────┤
│North Dakota │South Carolina│
└──────────────┴──────────────┘
Java
import java.util.*;
import java.util.stream.*;
public class StateNamePuzzle {
static String[] states = {"Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "Florida",
"Georgia", "hawaii", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma",
"Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming",
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory",};
public static void main(String[] args) {
solve(Arrays.asList(states));
}
static void solve(List<String> input) {
Map<String, String> orig = input.stream().collect(Collectors.toMap(
s -> s.replaceAll("\\s", "").toLowerCase(), s -> s, (s, a) -> s));
input = new ArrayList<>(orig.keySet());
Map<String, List<String[]>> map = new HashMap<>();
for (int i = 0; i < input.size() - 1; i++) {
String pair0 = input.get(i);
for (int j = i + 1; j < input.size(); j++) {
String[] pair = {pair0, input.get(j)};
String s = pair0 + pair[1];
String key = Arrays.toString(s.chars().sorted().toArray());
List<String[]> val = map.getOrDefault(key, new ArrayList<>());
val.add(pair);
map.put(key, val);
}
}
map.forEach((key, list) -> {
for (int i = 0; i < list.size() - 1; i++) {
String[] a = list.get(i);
for (int j = i + 1; j < list.size(); j++) {
String[] b = list.get(j);
if (Stream.of(a[0], a[1], b[0], b[1]).distinct().count() < 4)
continue;
System.out.printf("%s + %s = %s + %s %n", orig.get(a[0]),
orig.get(a[1]), orig.get(b[0]), orig.get(b[1]));
}
}
});
}
}
Output:
Wen Kory + Kory New = York New + New Kory Wen Kory + Kory New = York New + New York Wen Kory + Kory New = New Kory + New York Wen Kory + York New = Kory New + New Kory Wen Kory + York New = Kory New + New York Wen Kory + York New = New Kory + New York Wen Kory + New Kory = Kory New + York New Wen Kory + New Kory = Kory New + New York Wen Kory + New Kory = York New + New York Wen Kory + New York = Kory New + York New Wen Kory + New York = Kory New + New Kory Wen Kory + New York = York New + New Kory Kory New + York New = New Kory + New York Kory New + New Kory = York New + New York Kory New + New York = York New + New Kory South Dakota + North Carolina = North Dakota + South Carolina
jq
# Input: a string
# Output: an array, being the exploded form of the normalized input
def normalize:
explode
| map(if . >= 97 then (. - 97) elif . >= 65 then (. - 65) else empty end);
# Input: an array of strings
# Output: a dictionary with key:value pairs: normalizedString:string
def dictionary:
reduce .[] as $s ( {}; . + { ($s|normalize|implode): $s });
# Input: an array of strings (e.g. state names)
# Output: a stream of solutions
def solve:
# Given a pair of normalized state names as lists of integers:
def nletters: map(length) | add;
# input [[s1,s2], [t2,t2]]
def solved:
( .[0] | add | sort) == (.[1] | add | sort);
unique
| length as $l
| dictionary as $dictionary
| ($dictionary | keys | map(explode)) as $states
| reduce ( range(0; $l) as $s1
| range($s1+1; $l) as $s2
| range($s1+1; $l) as $t1
| select($s2 != $t1)
| range($t1+1; $l) as $t2
| select($s2 != $t2)
| [[$states[$s1], $states[$s2]], [$states[$t1], $states[$t2]]] ) as $quad
([];
if ($quad[0] | nletters) == ($quad[1] | nletters)
and ($quad | solved)
then . + [$quad | map( map( $dictionary[ implode ] ))]
else .
end)
| .[];
The task:
def States: [
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio",
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
];
def task:
"Real state names:",
(States | solve),
"",
"States together with fictional state names:",
(States + ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"] | solve) ;
task
- Output:
$ jq -c -n -r -f State_name_puzzle.jq
Real state names:
[["North Carolina","South Dakota"],["North Dakota","South Carolina"]]
States together with fictional state names:
[["Kory New","New Kory"],["New York","Wen Kory"]]
[["Kory New","New Kory"],["New York","York New"]]
[["Kory New","New Kory"],["Wen Kory","York New"]]
[["Kory New","New York"],["New Kory","Wen Kory"]]
[["Kory New","New York"],["New Kory","York New"]]
[["Kory New","New York"],["Wen Kory","York New"]]
[["Kory New","Wen Kory"],["New Kory","New York"]]
[["Kory New","Wen Kory"],["New Kory","York New"]]
[["Kory New","Wen Kory"],["New York","York New"]]
[["Kory New","York New"],["New Kory","New York"]]
[["Kory New","York New"],["New Kory","Wen Kory"]]
[["Kory New","York New"],["New York","Wen Kory"]]
[["New Kory","New York"],["Wen Kory","York New"]]
[["New Kory","Wen Kory"],["New York","York New"]]
[["New Kory","York New"],["New York","Wen Kory"]]
[["North Carolina","South Dakota"],["North Dakota","South Carolina"]]
Julia
Module:
module StateNamePuzzle
const realnames = ["Alabama", "Alaska", "Arizona", "Arkansas", "California",
"Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri",
"Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
"Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia",
"Wisconsin", "Wyoming"]
const fictitious = ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"]
function combine(a::AbstractString, b::AbstractString)
chars = vcat(collect(Char, a), collect(Char, b))
sort!(chars)
return join(chars)
end
function solve(input::Vector{<:AbstractString})
dict = Dict{String,String}()
for state in input
key = replace(state, " ", "") |> lowercase
if !haskey(dict, key)
dict[key] = state
end
end
keyset = collect(keys(dict))
solutions = String[]
duplicates = String[]
for i in eachindex(keyset), j in (i+1):endof(keyset)
len1 = length(keyset[i]) + length(keyset[j])
combined1 = combine(keyset[i], keyset[j])
for k in eachindex(keyset), l in k+1:endof(keyset)
k ∈ (i, j) && continue
l ∈ (i, j) && continue
len2 = length(keyset[k]) + length(keyset[l])
len1 != len2 && continue
combined2 = combine(keyset[k], keyset[l])
if combined1 == combined2
f1 = dict[keyset[i]] * " + " * dict[keyset[j]]
f2 = dict[keyset[k]] * " + " * dict[keyset[l]]
f3 = f1 * " = " * f2
f3 ∈ duplicates && continue
push!(solutions, f3)
f4 = f2 * " = " * f1
push!(duplicates, f4)
end
end
end
return sort!(solutions)
end
end # module StateNamePuzzle
Main:
println("Real states:")
foreach(println, StateNamePuzzle.solve(StateNamePuzzle.realnames))
println("\nReal + fictitious state:")
foreach(println, StateNamePuzzle.solve(vcat(StateNamePuzzle.realnames,
StateNamePuzzle.fictitious)))
- Output:
Real states: South Dakota + North Carolina = South Carolina + North Dakota Real + fictitious state: Kory New + New Kory = New York + York New Kory New + New Kory = Wen Kory + New York Kory New + New Kory = Wen Kory + York New Kory New + New York = New Kory + Wen Kory Kory New + New York = New Kory + York New Kory New + New York = Wen Kory + York New Kory New + Wen Kory = New Kory + New York Kory New + Wen Kory = New Kory + York New Kory New + Wen Kory = New York + York New Kory New + York New = New Kory + New York Kory New + York New = New Kory + Wen Kory Kory New + York New = Wen Kory + New York New Kory + New York = Wen Kory + York New New Kory + Wen Kory = New York + York New New Kory + York New = Wen Kory + New York South Dakota + North Carolina = South Carolina + North Dakota
Kotlin
// version 1.2.10
fun solve(states: List<String>) {
val dict = mutableMapOf<String, String>()
for (state in states) {
val key = state.toLowerCase().replace(" ", "")
if (dict[key] == null) dict.put(key, state)
}
val keys = dict.keys.toList()
val solutions = mutableListOf<String>()
val duplicates = mutableListOf<String>()
for (i in 0 until keys.size) {
for (j in i + 1 until keys.size) {
val len = keys[i].length + keys[j].length
val chars = (keys[i] + keys[j]).toCharArray()
chars.sort()
val combined = String(chars)
for (k in 0 until keys.size) {
for (l in k + 1 until keys.size) {
if (k == i || k == j || l == i || l == j) continue
val len2 = keys[k].length + keys[l].length
if (len2 != len) continue
val chars2 = (keys[k] + keys[l]).toCharArray()
chars2.sort()
val combined2 = String(chars2)
if (combined == combined2) {
val f1 = "${dict[keys[i]]} + ${dict[keys[j]]}"
val f2 = "${dict[keys[k]]} + ${dict[keys[l]]}"
val f3 = "$f1 = $f2"
if (f3 in duplicates) continue
solutions.add(f3)
val f4 = "$f2 = $f1"
duplicates.add(f4)
}
}
}
}
}
solutions.sort()
for ((i, sol) in solutions.withIndex()) {
println("%2d %s".format(i + 1, sol))
}
}
fun main(args: Array<String>) {
val states = listOf(
"Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut",
"Delaware",
"Florida", "Georgia", "Hawaii",
"Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
)
println("Real states only:")
solve(states)
println()
val fictitious = listOf(
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"
)
println("Real and fictitious states:")
solve(states + fictitious)
}
- Output:
Real states only: 1 North Carolina + South Dakota = North Dakota + South Carolina Real and fictitious states: 1 New Kory + Kory New = Wen Kory + York New 2 New Kory + Wen Kory = York New + Kory New 3 New Kory + York New = Wen Kory + Kory New 4 New York + Kory New = New Kory + Wen Kory 5 New York + Kory New = New Kory + York New 6 New York + Kory New = Wen Kory + York New 7 New York + New Kory = Wen Kory + Kory New 8 New York + New Kory = Wen Kory + York New 9 New York + New Kory = York New + Kory New 10 New York + Wen Kory = New Kory + Kory New 11 New York + Wen Kory = New Kory + York New 12 New York + Wen Kory = York New + Kory New 13 New York + York New = New Kory + Kory New 14 New York + York New = New Kory + Wen Kory 15 New York + York New = Wen Kory + Kory New 16 North Carolina + South Dakota = North Dakota + South Carolina
LiveCode
This is going to be O(N^2).
function pairwiseAnagrams X
if the optionkey is down then breakpoint
put the long seconds into T
put empty into itemsSoFar
repeat for each item W in X
put word 1 to -1 of W into W
if D[W] = 1 then next repeat
put 1 into D[W]
repeat for each item W2 in itemsSoFar
put W,W2 & cr after WPairs[sortChars(W & W2,true)]
end repeat
put W & comma after itemsSoFar
end repeat
repeat for each key K in WPairs
put empty into pairsSoFar
repeat for each line L in WPairs[K]
repeat for each line L2 in pairsSoFar
if item 1 of L is among the items of L2 or item 2 of L is among the items of L2 then next repeat
put L && "and" && L2 & cr after R
end repeat
put L & cr after pairsSoFar
end repeat
end repeat
put the long seconds - T
return char 1 to -2 of R
end pairwiseAnagrams
function sortChars X,lettersOnly
get charsToItems(X,lettersOnly)
sort items of it
return itemsToChars(it)
end sortChars
function charsToItems X,lettersOnly
repeat for each char C in X
if lettersOnly and C is not in "abcdefghijklmnopqrstuvwxyz" then next repeat
put C & comma after R
end repeat
return char 1 to -2 of R
end charsToItems
function itemsToChars X
replace comma with empty in X
return X
end itemsToChars
Mathematica/Wolfram Language
letters[words_,n_] := Sort[Flatten[Characters /@ Take[words,n]]];
groupSameQ[g1_, g2_] := Sort /@ Partition[g1, 2] === Sort /@ Partition[g2, 2];
permutations[{a_, b_, c_, d_}] = Union[Permutations[{a, b, c, d}], SameTest -> groupSameQ];
Select[Flatten[permutations /@
Subsets[Union[ToLowerCase/@{"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland",
"Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire",
"New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
"Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington",
"West Virginia", "Wisconsin", "Wyoming"}], {4}], 1],
letters[#, 2] === letters[#, -2] &]
Nim
import algorithm, sequtils, strformat, strutils, tables
const
States = @["Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware",
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois",
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"]
Fictitious = @["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"]
type MatchingPairs = ((string, string), (string, string))
proc matchingPairs(states: openArray[string]): seq[MatchingPairs] =
## Build the list of matching pairs of states.
let states = sorted(states).deduplicate()
# Build a mapping from ordered sequence of chars to sequence of (state, state).
var mapping: Table[seq[char], seq[(string, string)]]
for i in 0..<states.high:
let s1 = states[i]
for j in (i + 1)..states.high:
let s2 = states[j]
mapping.mgetOrPut(sorted(map(s1 & s2, toLowerAscii)), @[]).add (s1, s2)
# Keep only the couples of pairs of states with no common state.
for pairs in mapping.values:
if pairs.len > 1:
# These pairs are candidates.
for i in 0..<pairs.high:
let pair1 = pairs[i]
for j in i..pairs.high:
let pair2 = pairs[j]
if pair1[0] != pair2[0] and pair1[0] != pair2[1] and
pair1[1] != pair2[0] and pair1[1] != pair2[1]:
# "pair1" and "pair2" have no common state.
result.add (pair1, pair2)
proc `$`(pairs: MatchingPairs): string =
## Return the string representation of two matching pairs.
"$1 & $2 = $3 & $4".format(pairs[0][0], pairs[0][1], pairs[1][0], pairs[1][1])
echo "For real states:"
for n, pairs in matchingPairs(States):
echo &"{n+1:2}: {pairs}"
echo()
echo "For real + fictitious states:"
for n, pairs in matchingPairs(States & Fictitious):
echo &"{n+1:2}: {pairs}"
- Output:
For real states: 1: North Carolina & South Dakota = North Dakota & South Carolina For real + fictitious states: 1: North Carolina & South Dakota = North Dakota & South Carolina 2: Kory New & New Kory = New York & Wen Kory 3: Kory New & New Kory = New York & York New 4: Kory New & New Kory = Wen Kory & York New 5: Kory New & New York = New Kory & Wen Kory 6: Kory New & New York = New Kory & York New 7: Kory New & New York = Wen Kory & York New 8: Kory New & Wen Kory = New Kory & New York 9: Kory New & Wen Kory = New Kory & York New 10: Kory New & Wen Kory = New York & York New 11: Kory New & York New = New Kory & New York 12: Kory New & York New = New Kory & Wen Kory 13: Kory New & York New = New York & Wen Kory 14: New Kory & New York = Wen Kory & York New 15: New Kory & Wen Kory = New York & York New 16: New Kory & York New = New York & Wen Kory
Perl
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
sub uniq {
my %uniq;
undef @uniq{ @_ };
return keys %uniq
}
sub puzzle {
my @states = uniq(@_);
my %pairs;
for my $state1 (@states) {
for my $state2 (@states) {
next if $state1 le $state2;
my $both = join q(),
grep ' ' ne $_,
sort split //,
lc "$state1$state2";
push @{ $pairs{$both} }, [ $state1, $state2 ];
}
}
for my $pair (keys %pairs) {
next if 2 > @{ $pairs{$pair} };
for my $pair1 (@{ $pairs{$pair} }) {
for my $pair2 (@{ $pairs{$pair} }) {
next if 4 > uniq(@$pair1, @$pair2)
or $pair1->[0] lt $pair2->[0];
say join ' = ', map { join ' + ', @$_ } $pair1, $pair2;
}
}
}
}
my @states = ( 'Alabama', 'Alaska', 'Arizona', 'Arkansas',
'California', 'Colorado', 'Connecticut', 'Delaware',
'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa',
'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan',
'Minnesota', 'Mississippi', 'Missouri', 'Montana',
'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey',
'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon',
'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas',
'Utah', 'Vermont', 'Virginia',
'Washington', 'West Virginia', 'Wisconsin', 'Wyoming',
);
my @fictious = ( 'New Kory', 'Wen Kory', 'York New', 'Kory New', 'New Kory' );
say scalar @states, ' states:';
puzzle(@states);
say @states + @fictious, ' states:';
puzzle(@states, @fictious);
Phix
with javascript_semantics constant states = {"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"}, -- extras = {"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"} extras = {"Slender Dragon", "Abalamara"} function no_dup(sequence s) s = sort(s) for i=length(s) to 2 by -1 do if s[i]=s[i-1] then s[i] = s[$] s = s[1..$-1] end if end for return s end function procedure play(sequence s) s = no_dup(deep_copy(s)) destroy_dict(1) -- empty dict for i=1 to length(s)-1 do for j=i+1 to length(s) do string key = trim(sort(lower(s[i]&s[j]))) object data = getd(key) if data=0 then putd(key,{{i,j}}) else for k=1 to length(data) do integer {m,n} = data[k] if m!=i and m!=j and n!=i and n!=j then ?{s[i],s[j],"<==>",s[m],s[n]} end if end for putd(key,append(deep_copy(data),{i,j})) end if end for end for end procedure play(states) ?"===" play(states&extras)
- Output:
{"North Dakota","South Carolina","<==>","North Carolina","South Dakota"} "===" {"Alabama","Arkansas","<==>","Abalamara","Kansas"} {"North Dakota","South Carolina","<==>","North Carolina","South Dakota"} {"Oregon","Rhode Island","<==>","Ohio","Slender Dragon"}
PicoLisp
(setq *States
(group
(mapcar '((Name) (cons (clip (sort (chop (lowc Name)))) Name))
(quote
"Alabama" "Alaska" "Arizona" "Arkansas"
"California" "Colorado" "Connecticut"
"Delaware"
"Florida" "Georgia" "Hawaii"
"Idaho" "Illinois" "Indiana" "Iowa"
"Kansas" "Kentucky" "Louisiana"
"Maine" "Maryland" "Massachusetts" "Michigan"
"Minnesota" "Mississippi" "Missouri" "Montana"
"Nebraska" "Nevada" "New Hampshire" "New Jersey"
"New Mexico" "New York" "North Carolina" "North Dakota"
"Ohio" "Oklahoma" "Oregon"
"Pennsylvania" "Rhode Island"
"South Carolina" "South Dakota" "Tennessee" "Texas"
"Utah" "Vermont" "Virginia"
"Washington" "West Virginia" "Wisconsin" "Wyoming"
"New Kory" "Wen Kory" "York New" "Kory New" "New Kory" ) ) ) )
(extract
'((P)
(when (cddr P)
(mapcar
'((X)
(cons
(cadr (assoc (car X) *States))
(cadr (assoc (cdr X) *States)) ) )
(cdr P) ) ) )
(group
(mapcon
'((X)
(extract
'((Y)
(cons
(sort (conc (copy (caar X)) (copy (car Y))))
(caar X)
(car Y) ) )
(cdr X) ) )
*States ) ) )
Output:
-> ((("North Carolina" . "South Dakota") ("North Dakota" . "South Carolina")))
Prolog
Works with SWI-Prolog. Use of Goedel numbers.
state_name_puzzle :-
L = ["Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut",
"Delaware",
"Florida", "Georgia", "Hawaii",
"Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming",
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory"],
maplist(goedel, L, R),
% sort remove duplicates
sort(R, RS),
study(RS).
study([]).
study([V-Word|T]) :-
study_1_Word(V-Word, T, T),
study(T).
study_1_Word(_, [], _).
study_1_Word(V1-W1, [V2-W2 | T1], T) :-
TT is V1+V2,
study_2_Word(W1, W2, TT, T),
study_1_Word(V1-W1, T1, T).
study_2_Word(_W1, _W2, _TT, []).
study_2_Word(W1, W2, TT, [V3-W3 | T]) :-
( W2 \= W3 -> study_3_Word(W1, W2, TT, V3-W3, T); true),
study_2_Word(W1, W2, TT, T).
study_3_Word(_W1, _W2, _TT, _V3-_W3, []).
study_3_Word(W1, W2, TT, V3-W3, [V4-W4|T]) :-
TT1 is V3 + V4,
( TT1 < TT -> study_3_Word(W1, W2, TT, V3-W3, T)
; (TT1 = TT -> ( W4 \= W2 -> format('~w & ~w with ~w & ~w~n', [W1, W2, W3, W4])
; true),
study_3_Word(W1, W2, TT, V3-W3, T))
; true).
% Compute a Goedel number for the word
goedel(Word, Goedel-A) :-
name(A, Word),
downcase_atom(A, Amin),
atom_codes(Amin, LA),
compute_Goedel(LA, 0, Goedel).
compute_Goedel([], G, G).
compute_Goedel([32|T], GC, GF) :-
compute_Goedel(T, GC, GF).
compute_Goedel([H|T], GC, GF) :-
Ind is H - 97,
GC1 is GC + 26 ** Ind,
compute_Goedel(T, GC1, GF).
Output :
?- time(state_name_puzzle). North Carolina & South Dakota with North Dakota & South Carolina Kory New & New Kory with New York & Wen Kory Kory New & New Kory with New York & York New Kory New & New Kory with Wen Kory & York New Kory New & New York with New Kory & Wen Kory Kory New & New York with New Kory & York New Kory New & New York with Wen Kory & York New Kory New & Wen Kory with New Kory & New York Kory New & Wen Kory with New Kory & York New Kory New & Wen Kory with New York & York New Kory New & York New with New Kory & New York Kory New & York New with New Kory & Wen Kory Kory New & York New with New York & Wen Kory New Kory & New York with Wen Kory & York New New Kory & Wen Kory with New York & York New New Kory & York New with New York & Wen Kory % 1,076,511 inferences, 1.078 CPU in 1.141 seconds (94% CPU, 998503 Lips) true .
Python
from collections import defaultdict
states = ["Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas",
"Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma",
"Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming",
# Uncomment the next line for the fake states.
# "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"
]
states = sorted(set(states))
smap = defaultdict(list)
for i, s1 in enumerate(states[:-1]):
for s2 in states[i + 1:]:
smap["".join(sorted(s1 + s2))].append(s1 + " + " + s2)
for pairs in sorted(smap.itervalues()):
if len(pairs) > 1:
print " = ".join(pairs)
Racket
#lang racket
(define states
(list->set
(map string-downcase
'("Alabama" "Alaska" "Arizona" "Arkansas"
"California" "Colorado" "Connecticut"
"Delaware"
"Florida" "Georgia" "Hawaii"
"Idaho" "Illinois" "Indiana" "Iowa"
"Kansas" "Kentucky" "Louisiana"
"Maine" "Maryland" "Massachusetts" "Michigan"
"Minnesota" "Mississippi" "Missouri" "Montana"
"Nebraska""Nevada" "New Hampshire" "New Jersey"
"New Mexico" "New York" "North Carolina" "North Dakota"
"Ohio" "Oklahoma" "Oregon"
"Pennsylvania" "Rhode Island"
"South Carolina" "South Dakota" "Tennessee" "Texas"
"Utah" "Vermont" "Virginia"
"Washington" "West Virginia" "Wisconsin" "Wyoming"
; "New Kory" "Wen Kory" "York New" "Kory New" "New Kory"
))))
(define (canon s t)
(sort (append (string->list s) (string->list t)) char<? ))
(define seen (make-hash))
(for* ([s1 states] [s2 states] #:when (string<? s1 s2))
(define c (canon s1 s2))
(cond [(hash-ref seen c (λ() (hash-set! seen c (list s1 s2)) #f))
=> (λ(states) (displayln (~v states (list s1 s2))))]))
Output:
'("north dakota" "south carolina") '("north carolina" "south dakota")
Raku
(formerly Perl 6)
my @states = <
Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware
Florida Georgia Hawaii Idaho Illinois Indiana Iowa Kansas Kentucky
Louisiana Maine Maryland Massachusetts Michigan Minnesota Mississippi
Missouri Montana Nebraska Nevada New_Hampshire New_Jersey New_Mexico
New_York North_Carolina North_Dakota Ohio Oklahoma Oregon Pennsylvania
Rhode_Island South_Carolina South_Dakota Tennessee Texas Utah Vermont
Virginia Washington West_Virginia Wisconsin Wyoming
>;
say "50 states:";
.say for anastates @states;
say "\n54 states:";
.say for sort anastates @states, < New_Kory Wen_Kory York_New Kory_New New_Kory >;
sub anastates (*@states) {
my @s = @states.unique».subst('_', ' ');
my @pairs = gather for ^@s -> $i {
for $i ^..^ @s -> $j {
take [ @s[$i], @s[$j] ];
}
}
my $equivs = hash @pairs.classify: *.lc.comb.sort.join;
gather for $equivs.values -> @c {
for ^@c -> $i {
for $i ^..^ @c -> $j {
my $set = set @c[$i].list, @c[$j].list;
take @c[$i].list.join(', ') ~ ' = ' ~ @c[$j].list.join(', ') if $set == 4;
}
}
}
}
Output:
50 states: North Carolina, South Dakota = North Dakota, South Carolina 54 states: New Kory, Kory New = Wen Kory, York New New Kory, Wen Kory = York New, Kory New New Kory, York New = Wen Kory, Kory New New York, Kory New = New Kory, Wen Kory New York, Kory New = New Kory, York New New York, Kory New = Wen Kory, York New New York, New Kory = Wen Kory, Kory New New York, New Kory = Wen Kory, York New New York, New Kory = York New, Kory New New York, Wen Kory = New Kory, Kory New New York, Wen Kory = New Kory, York New New York, Wen Kory = York New, Kory New New York, York New = New Kory, Kory New New York, York New = New Kory, Wen Kory New York, York New = Wen Kory, Kory New North Carolina, South Dakota = North Dakota, South Carolina
REXX
Code was added to the REXX program to remove dead-end words (state names) that can't possibly be part of
a solution, in particular, words that contain a unique letter (among all the state names).
/*REXX program (state name puzzle) rearranges two state's names ──► two new states. */
!='Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware, Florida, Georgia,',
'Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, ',
'Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, New Hampshire, New Jersey, New Mexico,',
'New York, North Carolina, North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,',
'South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia, Wisconsin, Wyoming'
parse arg xtra; !=! ',' xtra /*add optional (fictitious) names.*/
@abcU= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; !=space(!) /*!: the state list, no extra blanks*/
deads=0; dups=0; L.=0; !orig=!; @@.= /*initialize some REXX variables. */
z=0 /* [↑] elide dend─end (DE) states.*/
do de=0 for 2; !=!orig /*use original state list for each. */
@.=
do states=0 by 0 until !=='' /*parse until the cows come home. */
parse var ! x ',' !; x=space(x) /*remove all blanks from state name.*/
if @.x\=='' then do /*was state was already specified? */
if de then iterate /*don't tell error if doing 2nd pass*/
dups=dups + 1 /*bump the duplicate counter. */
say 'ignoring the 2nd naming of the state: ' x; iterate
end
@.x=x /*indicate this state name exists. */
y=space(x,0); upper y; yLen=length(y) /*get upper name with no spaces; Len*/
if de then do /*Is the firstt pass? Then process.*/
do j=1 for yLen /*see if it's a dead─end state name.*/
_=substr(y, j, 1) /* _: is some state name character.*/
if L._ \== 1 then iterate /*Count ¬ 1? Then state name is OK.*/
say 'removing dead─end state [which has the letter ' _"]: " x
deads=deads + 1 /*bump number of dead─ends states. */
iterate states /*go and process another state name.*/
end /*j*/
z=z+1 /*bump counter of the state names. */
#.z=y; ##.z=x /*assign state name; also original.*/
end
else do k=1 for yLen /*inventorize letters of state name.*/
_=substr(y,k,1); L._=L._ + 1 /*count each letter in state name. */
end /*k*/
end /*states*/ /*the index STATES isn't incremented*/
end /*de*/
call list /*list state names in order given. */
say z 'state name's(z) "are useable."
if dups \==0 then say dups 'duplicate of a state's(dups) 'ignored.'
if deads\==0 then say deads 'dead─end state's(deads) 'deleted.'
sols=0 /*number of solutions found (so far)*/
say /*[↑] look for mix and match states*/
do j=1 for z /* ◄──────────────────────────────────────────────────────────┐ */
do k=j+1 to z /* ◄─── state K, state J ►─────┘ */
if #.j<<#.k then JK=#.j || #.k /*is the state in the proper order? */
else JK=#.k || #.j /*No, then use the new state name. */
do m=1 for z; if m==j | m==k then iterate /*no state overlaps are allowed. */
if verify(#.m, jk) \== 0 then iterate /*is this state name even possible? */
nJK=elider(JK, #.m) /*a new JK, after eliding #.m chars.*/
do n=m+1 to z; if n==j | n==k then iterate /*no overlaps are allowed. */
if verify(#.n, nJK) \== 0 then iterate /*is it possible? */
if elider(nJK, #.n) \== '' then iterate /*any leftovers letters? */
if #.m<<#.n then MN=#.m || #.n /*is it in the proper order?*/
else MN=#.n || #.m /*we found a new state name.*/
if @@.JK.MN\=='' | @@.MN.JK\=="" then iterate /*was it done before? */
say 'found: ' ##.j',' ##.k " ───► " ##.m',' ##.n
@@.JK.MN=1 /*indicate this solution as being found*/
sols=sols+1 /*bump the number of solutions found. */
end /*n*/
end /*m*/
end /*k*/
end /*j*/
say /*show a blank line for easier reading.*/
if sols==0 then sols= 'No' /*use mucher gooder (sic) Englishings. */
say sols 'solution's(sols) "found." /*display the number of solutions found*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
elider: parse arg hay,pins /*remove letters (pins) from haystack. */
do e=1 for length(pins); p=pos( substr( pins, e, 1), hay)
if p==0 then iterate ; hay=overlay(' ', hay, p)
end /*e*/ /* [↑] remove a letter from haystack. */
return space(hay, 0) /*remove blanks from the haystack. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
list: say; do i=1 for z; say right(i, 9) ##.i; end; say; return
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*pluralizer.*/
- output when using the default input:
removing dead─end state [which has the letter Z]: Arizona removing dead─end state [which has the letter J]: New Jersey 1 Alabama 2 Alaska 3 Arkansas 4 California 5 Colorado 6 Connecticut 7 Delaware 8 Florida 9 Georgia 10 Hawaii 11 Idaho 12 Illinois 13 Indiana 14 Iowa 15 Kansas 16 Kentucky 17 Louisiana 18 Maine 19 Maryland 20 Massachusetts 21 Michigan 22 Minnesota 23 Mississippi 24 Missouri 25 Montana 26 Nebraska 27 Nevada 28 New Hampshire 29 New Mexico 30 New York 31 North Carolina 32 North Dakota 33 Ohio 34 Oklahoma 35 Oregon 36 Pennsylvania 37 Rhode Island 38 South Carolina 39 South Dakota 40 Tennessee 41 Texas 42 Utah 43 Vermont 44 Virginia 45 Washington 46 West Virginia 47 Wisconsin 48 Wyoming 48 state names are useable. 2 dead─end states deleted. found: North Carolina, South Dakota ───► North Dakota, South Carolina 1 solution found.
output when using the input of: New Kory, Wen Kory, York New, Kory New, New Kory
ignoring the 2nd naming of the state: New Kory removing dead─end state [which has the letter Z]: Arizona removing dead─end state [which has the letter J]: New Jersey 1 Alabama 2 Alaska 3 Arkansas 4 California 5 Colorado 6 Connecticut 7 Delaware 8 Florida 9 Georgia 10 Hawaii 11 Idaho 12 Illinois 13 Indiana 14 Iowa 15 Kansas 16 Kentucky 17 Louisiana 18 Maine 19 Maryland 20 Massachusetts 21 Michigan 22 Minnesota 23 Mississippi 24 Missouri 25 Montana 26 Nebraska 27 Nevada 28 New Hampshire 29 New Mexico 30 New York 31 North Carolina 32 North Dakota 33 Ohio 34 Oklahoma 35 Oregon 36 Pennsylvania 37 Rhode Island 38 South Carolina 39 South Dakota 40 Tennessee 41 Texas 42 Utah 43 Vermont 44 Virginia 45 Washington 46 West Virginia 47 Wisconsin 48 Wyoming 49 New Kory 50 Wen Kory 51 York New 52 Kory New 52 state names are useable. 1 duplicate of a state ignored. 2 dead─end states deleted. found: New York, New Kory ───► Wen Kory, York New found: New York, New Kory ───► Wen Kory, Kory New found: New York, New Kory ───► York New, Kory New found: New York, Wen Kory ───► New Kory, York New found: New York, Wen Kory ───► New Kory, Kory New found: New York, Wen Kory ───► York New, Kory New found: New York, York New ───► New Kory, Wen Kory found: New York, York New ───► New Kory, Kory New found: New York, York New ───► Wen Kory, Kory New found: New York, Kory New ───► New Kory, Wen Kory found: New York, Kory New ───► New Kory, York New found: New York, Kory New ───► Wen Kory, York New found: North Carolina, South Dakota ───► North Dakota, South Carolina found: New Kory, Wen Kory ───► York New, Kory New found: New Kory, York New ───► Wen Kory, Kory New found: New Kory, Kory New ───► Wen Kory, York New 16 solutions found.
Ruby
require 'set'
# 26 prime numbers
Primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
States = [
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio",
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
]
def print_answer(states)
# find goedel numbers for all pairs of states
goedel = lambda {|str| str.chars.map {|c| Primes[c.ord - 65]}.reduce(:*)}
pairs = Hash.new {|h,k| h[k] = Array.new}
map = states.uniq.map {|state| [state, goedel[state.upcase.delete("^A-Z")]]}
map.combination(2) {|(s1,g1), (s2,g2)| pairs[g1 * g2] << [s1, s2]}
# find pairs without duplicates
result = []
pairs.values.select {|val| val.length > 1}.each do |list_of_pairs|
list_of_pairs.combination(2) do |pair1, pair2|
if Set[*pair1, *pair2].length == 4
result << [pair1, pair2]
end
end
end
# output the results
result.each_with_index do |(pair1, pair2), i|
puts "%d\t%s\t%s" % [i+1, pair1.join(', '), pair2.join(', ')]
end
end
puts "real states only"
print_answer(States)
puts ""
puts "with fictional states"
print_answer(States + ["New Kory", "Wen Kory", "York New", "Kory New", "New Kory"])
outputs
real states only 1 North Carolina, South Dakota North Dakota, South Carolina with fictional states 1 New York, New Kory Wen Kory, York New 2 New York, New Kory Wen Kory, Kory New 3 New York, New Kory York New, Kory New 4 New York, Wen Kory New Kory, York New 5 New York, Wen Kory New Kory, Kory New 6 New York, Wen Kory York New, Kory New 7 New York, York New New Kory, Wen Kory 8 New York, York New New Kory, Kory New 9 New York, York New Wen Kory, Kory New 10 New York, Kory New New Kory, Wen Kory 11 New York, Kory New New Kory, York New 12 New York, Kory New Wen Kory, York New 13 New Kory, Wen Kory York New, Kory New 14 New Kory, York New Wen Kory, Kory New 15 New Kory, Kory New Wen Kory, York New 16 North Carolina, South Dakota North Dakota, South Carolina
Scala
object StateNamePuzzle extends App {
// Logic:
def disjointPairs(pairs: Seq[Set[String]]) =
for (a <- pairs; b <- pairs; if a.intersect(b).isEmpty) yield Set(a,b)
def anagramPairs(words: Seq[String]) =
(for (a <- words; b <- words; if a != b) yield Set(a, b)) // all pairs
.groupBy(_.mkString.toLowerCase.replaceAll("[^a-z]", "").sorted) // grouped anagram pairs
.values.map(disjointPairs).flatMap(_.distinct) // unique non-overlapping anagram pairs
// Test:
val states = List(
"New Kory", "Wen Kory", "York New", "Kory New", "New Kory",
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio",
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
)
println(anagramPairs(states).map(_.map(_ mkString " + ") mkString " = ") mkString "\n")
}
- Output:
New Kory + Wen Kory = York New + Kory New New Kory + Wen Kory = York New + New York New Kory + Wen Kory = Kory New + New York New Kory + York New = Wen Kory + Kory New New Kory + York New = Wen Kory + New York New Kory + York New = Kory New + New York New Kory + Kory New = Wen Kory + York New New Kory + Kory New = Wen Kory + New York New Kory + Kory New = York New + New York New Kory + New York = Wen Kory + York New New Kory + New York = Wen Kory + Kory New New Kory + New York = York New + Kory New Wen Kory + York New = Kory New + New York Wen Kory + Kory New = York New + New York Wen Kory + New York = York New + Kory New North Carolina + South Dakota = North Dakota + South Carolina
Tcl
package require Tcl 8.5
# Gödel number generator
proc goedel s {
set primes {
2 3 5 7 11 13 17 19 23 29 31 37 41
43 47 53 59 61 67 71 73 79 83 89 97 101
}
set n 1
foreach c [split [string toupper $s] ""] {
if {![string is alpha $c]} continue
set n [expr {$n * [lindex $primes [expr {[scan $c %c] - 65}]]}]
}
return $n
}
# Calculates the pairs of states
proc groupStates {stateList} {
set stateList [lsort -unique $stateList]
foreach state1 $stateList {
foreach state2 $stateList {
if {$state1 >= $state2} continue
dict lappend group [goedel $state1$state2] [list $state1 $state2]
}
}
foreach g [dict values $group] {
if {[llength $g] > 1} {
foreach p1 $g {
foreach p2 $g {
if {$p1 < $p2 && [unshared $p1 $p2]} {
lappend result [list $p1 $p2]
}
}
}
}
}
return $result
}
proc unshared args {
foreach p $args {
foreach a $p {incr s($a)}
}
expr {[array size s] == [llength $args]*2}
}
# Pretty printer for state name pair lists
proc printPairs {title groups} {
foreach group $groups {
puts "$title Group #[incr count]"
foreach statePair $group {
puts "\t[join $statePair {, }]"
}
}
}
set realStates {
"Alabama" "Alaska" "Arizona" "Arkansas" "California" "Colorado"
"Connecticut" "Delaware" "Florida" "Georgia" "Hawaii" "Idaho" "Illinois"
"Indiana" "Iowa" "Kansas" "Kentucky" "Louisiana" "Maine" "Maryland"
"Massachusetts" "Michigan" "Minnesota" "Mississippi" "Missouri" "Montana"
"Nebraska" "Nevada" "New Hampshire" "New Jersey" "New Mexico" "New York"
"North Carolina" "North Dakota" "Ohio" "Oklahoma" "Oregon" "Pennsylvania"
"Rhode Island" "South Carolina" "South Dakota" "Tennessee" "Texas" "Utah"
"Vermont" "Virginia" "Washington" "West Virginia" "Wisconsin" "Wyoming"
}
printPairs "Real States" [groupStates $realStates]
set falseStates {
"New Kory" "Wen Kory" "York New" "Kory New" "New Kory"
}
printPairs "Real and False States" [groupStates [concat $realStates $falseStates]]
Output:
Real States Group #1 North Carolina, South Dakota North Dakota, South Carolina Real and False States Group #1 Kory New, New Kory New York, Wen Kory Real and False States Group #2 Kory New, New Kory New York, York New Real and False States Group #3 Kory New, New Kory Wen Kory, York New Real and False States Group #4 Kory New, New York New Kory, Wen Kory Real and False States Group #5 Kory New, New York New Kory, York New Real and False States Group #6 Kory New, New York Wen Kory, York New Real and False States Group #7 Kory New, Wen Kory New Kory, New York Real and False States Group #8 Kory New, Wen Kory New Kory, York New Real and False States Group #9 Kory New, Wen Kory New York, York New Real and False States Group #10 Kory New, York New New Kory, New York Real and False States Group #11 Kory New, York New New Kory, Wen Kory Real and False States Group #12 Kory New, York New New York, Wen Kory Real and False States Group #13 New Kory, New York Wen Kory, York New Real and False States Group #14 New Kory, Wen Kory New York, York New Real and False States Group #15 New Kory, York New New York, Wen Kory Real and False States Group #16 North Carolina, South Dakota North Dakota, South Carolina
Wren
import "./str" for Str
import "./sort" for Sort
import "./fmt" for Fmt
var solve = Fn.new { |states|
var dict = {}
for (state in states) {
var key = Str.lower(state).replace(" ", "")
if (!dict[key]) dict[key] = state
}
var keys = dict.keys.toList
Sort.quick(keys)
var solutions = []
var duplicates = []
for (i in 0...keys.count) {
for (j in i+1...keys.count) {
var len = keys[i].count + keys[j].count
var chars = (keys[i] + keys[j]).toList
Sort.quick(chars)
var combined = chars.join()
for (k in 0...keys.count) {
for (l in k+1...keys.count) {
if (k != i && k != j && l != i && l != j) {
var len2 = keys[k].count + keys[l].count
if (len2 == len) {
var chars2 = (keys[k] + keys[l]).toList
Sort.quick(chars2)
var combined2 = chars2.join()
if (combined == combined2) {
var f1 = "%(dict[keys[i]]) + %(dict[keys[j]])"
var f2 = "%(dict[keys[k]]) + %(dict[keys[l]])"
var f3 = "%(f1) = %(f2)"
if (!duplicates.contains(f3)) {
solutions.add(f3)
var f4 = "%(f2) = %(f1)"
duplicates.add(f4)
}
}
}
}
}
}
}
}
Sort.quick(solutions)
var i = 0
for (sol in solutions) {
Fmt.print("$2d $s", i + 1, sol)
i = i + 1
}
}
var states = [
"Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut",
"Delaware",
"Florida", "Georgia", "Hawaii",
"Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana",
"Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"
]
System.print("Real states only:")
solve.call(states)
System.print()
var fictitious = [ "New Kory", "Wen Kory", "York New", "Kory New", "New Kory" ]
System.print("Real and fictitious states:")
solve.call(states + fictitious)
- Output:
Real states only: 1 North Carolina + South Dakota = North Dakota + South Carolina Real and fictitious states: 1 Kory New + New Kory = New York + Wen Kory 2 Kory New + New Kory = New York + York New 3 Kory New + New Kory = Wen Kory + York New 4 Kory New + New York = New Kory + Wen Kory 5 Kory New + New York = New Kory + York New 6 Kory New + New York = Wen Kory + York New 7 Kory New + Wen Kory = New Kory + New York 8 Kory New + Wen Kory = New Kory + York New 9 Kory New + Wen Kory = New York + York New 10 Kory New + York New = New Kory + New York 11 Kory New + York New = New Kory + Wen Kory 12 Kory New + York New = New York + Wen Kory 13 New Kory + New York = Wen Kory + York New 14 New Kory + Wen Kory = New York + York New 15 New Kory + York New = New York + Wen Kory 16 North Carolina + South Dakota = North Dakota + South Carolina
zkl
#<<< // here doc
states:=("Alabama, Alaska, Arizona, Arkansas,
California, Colorado, Connecticut, Delaware, Florida,
Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas,
Kentucky, Louisiana, Maine, Maryland, Massachusetts,
Michigan, Minnesota, Mississippi, Missouri, Montana,
Nebraska, Nevada, New Hampshire, New Jersey, New Mexico,
New York, North Carolina, North Dakota, Ohio, Oklahoma,
Oregon, Pennsylvania, Rhode Island, South Carolina,
South Dakota, Tennessee, Texas, Utah, Vermont, Virginia,
Washington, West Virginia, Wisconsin, Wyoming"
/* Uncomment the next line for the fake states. */
# ",New Kory, Wen Kory, York New, Kory New, New Kory"
#<<<
).split(",").apply("strip");
smap:=Dictionary();
Utils.Helpers.pickNFrom(2,states).apply2('wrap(ss){ // 1225 combinations
key:=(ss.concat()).toLower().sort()-" ";
smap[key]=smap.find(key,List()).append(ss.concat(" + "));
});
foreach pairs in (smap.values){ // 1224 keys
// pairs=Utils.Helpers.listUnique(pairs); // eliminate dups
if(pairs.len()>1)
println(pairs.concat(" = ")) }
- Output:
North Carolina + South Dakota = North Dakota + South Carolina