2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,105 +1,99 @@
|
|||
#include <stdio.h>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// some common code
|
||||
template<class C_, class LT_> C_ Unique(const C_& src, const LT_& less)
|
||||
template<typename T>
|
||||
T unique(T&& src)
|
||||
{
|
||||
C_ retval(src);
|
||||
std::sort(retval.begin(), retval.end(), less);
|
||||
retval.erase(unique(retval.begin(), retval.end()), retval.end());
|
||||
return retval;
|
||||
}
|
||||
template<class C_> C_ Unique(const C_& src)
|
||||
{
|
||||
return Unique(src, std::less<C_::value_type>());
|
||||
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
|
||||
|
||||
vector<string> states = Unique(vector<string>({
|
||||
auto states = unique(std::vector<std::string>({
|
||||
#if USE_FAKES
|
||||
"Slender Dragon", "Abalamara",
|
||||
"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"
|
||||
"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 CountedPair_
|
||||
struct counted_pair
|
||||
{
|
||||
string name_;
|
||||
vector<unsigned char> count_;
|
||||
std::string name;
|
||||
std::array<int, 26> count{};
|
||||
|
||||
void Add(const string& s)
|
||||
{
|
||||
for (auto c : s)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z') ++count_[c - 'a'];
|
||||
if (c >= 'A' && c <= 'Z') ++count_[c - 'A'];
|
||||
}
|
||||
}
|
||||
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']++;
|
||||
}
|
||||
}
|
||||
|
||||
CountedPair_(const string& s1, const string& s2) : name_(s1 + " + " + s2), count_(26, 0u)
|
||||
{
|
||||
Add(s1); Add(s2);
|
||||
}
|
||||
counted_pair(const std::string& s1, const std::string& s2)
|
||||
: name(s1 + " + " + s2)
|
||||
{
|
||||
count_characters(s1);
|
||||
count_characters(s2);
|
||||
}
|
||||
};
|
||||
|
||||
bool operator<(const CountedPair_& lhs, const CountedPair_& rhs)
|
||||
bool operator<(const counted_pair& lhs, const counted_pair& rhs)
|
||||
{
|
||||
const int s1 = lhs.name_.size(), s2 = rhs.name_.size();
|
||||
return s1 == s2
|
||||
? lexicographical_compare(lhs.count_.begin(), lhs.count_.end(), rhs.count_.begin(), rhs.count_.end())
|
||||
: s1 < s2;
|
||||
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 CountedPair_& lhs, const CountedPair_& rhs)
|
||||
bool operator==(const counted_pair& lhs, const counted_pair& rhs)
|
||||
{
|
||||
return lhs.name_.size() == rhs.name_.size()
|
||||
&& lhs.count_ == rhs.count_;
|
||||
return lhs.name.size() == rhs.name.size() && lhs.count == rhs.count;
|
||||
}
|
||||
|
||||
void FindPairs()
|
||||
int main()
|
||||
{
|
||||
const int n_states = states.size();
|
||||
const int n_states = states.size();
|
||||
|
||||
vector<CountedPair_> pairs;
|
||||
for (int i = 0; i < n_states; i++)
|
||||
for (int j = 0; j < i; j++)
|
||||
pairs.emplace_back(states[i], states[j]);
|
||||
sort(pairs.begin(), pairs.end());
|
||||
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();
|
||||
for (;;)
|
||||
{
|
||||
auto match = adjacent_find(start, pairs.end());
|
||||
if (match == pairs.end())
|
||||
break;
|
||||
auto next = match + 1;
|
||||
cout << match->name_ << " => " << next->name_ << "\n";
|
||||
start = next;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
FindPairs();
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,7 @@ public class StateNamePuzzle {
|
|||
String s = pair0 + pair[1];
|
||||
String key = Arrays.toString(s.chars().sorted().toArray());
|
||||
|
||||
List<String[]> val;
|
||||
if ((val = map.get(key)) == null)
|
||||
val = new ArrayList<>();
|
||||
List<String[]> val = map.getOrDefault(key, new ArrayList<>());
|
||||
val.add(pair);
|
||||
map.put(key, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ sub anastates (*@states) {
|
|||
}
|
||||
}
|
||||
|
||||
my $equivs = hash @pairs.classify: *.lc.comb.sort.join.trim;
|
||||
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 $set.join(', ') if $set == 4;
|
||||
take $set.keys.join(', ') if $set == 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,88 +1,86 @@
|
|||
/*REXX pgm (state name puzzle) rearranges two state's names ──► two new states*/
|
||||
/*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(!) /*ABCs; the state list.*/
|
||||
deads=0; dups=0; L.=0; !orig=!; z=0; @@.= /*initialize some vars. */
|
||||
parse arg xtra; !=! ',' xtra /*add optional (fictitious) names.*/
|
||||
@abcU='ABCDEFGHIJKLMNOPQRSTUVWXYZ'; !=space(!) /*!: the state list, no extra blanks*/
|
||||
deads=0; dups=0; L.=0; !orig=!; z=0; @@.= /*initialize some REXX variables. */
|
||||
|
||||
do de=0 for 2; !=!orig; @.= /*use original state list for each. */
|
||||
do de=0 for 2; !=!orig; @.= /*use original state list for each. */
|
||||
|
||||
do states=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. */
|
||||
do states=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*/
|
||||
@.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 1st 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 O.K.*/
|
||||
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; and original. */
|
||||
end
|
||||
else do k=1 for yLen /*inventorize state name's letters. */
|
||||
_=substr(y,k,1); L._=L._+1 /*count each letter in state name. */
|
||||
end /*k*/
|
||||
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; and original. */
|
||||
end
|
||||
else do k=1 for yLen /*inventorize state name's letters. */
|
||||
_=substr(y,k,1); L._=L._+1 /*count each letter in state name. */
|
||||
end /*k*/
|
||||
|
||||
end /*states*/
|
||||
end /*de*/
|
||||
|
||||
say; do i=1 for z /*list state names in order given. */
|
||||
say right(i,9) ##.i /*show the index number, state name.*/
|
||||
say; do i=1 for z /*list state names in order given. */
|
||||
say right(i,9) ##.i /*show the index number, state name.*/
|
||||
end /*i*/
|
||||
|
||||
say; 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.'
|
||||
say; 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.'
|
||||
say
|
||||
sols=0 /*number of solutions found (so far)*/
|
||||
sols=0 /*number of solutions found (so far)*/
|
||||
|
||||
do j=1 for z /*◄─────────────────────────────────────────────────────┐ */
|
||||
/*look for mix and match states. │ */
|
||||
do k=j+1 to z /* ◄─── state K, state J ►───────┘ */
|
||||
if #.j<<#.k then JK=#.j || #.k /*is in proper order?*/
|
||||
else JK=#.k || #.j /*use new state name.*/
|
||||
do j=1 for z /*◄───────────────────────────────────────────────────────────────┐ */
|
||||
/*look for mix and match states. │ */
|
||||
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 overlaps allowed*/
|
||||
if verify(#.m,jk)\==0 then iterate /*is this possible? */
|
||||
nJK=elider(JK,#.m) /*new JK, after eliding #.m characters.*/
|
||||
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 allowed*/
|
||||
if verify(#.n,nJK)\==0 then iterate /*is it possible? */
|
||||
if elider(nJK,#.n)\=='' then iterate /*leftovers letters? */
|
||||
if #.m<<#.n then MN=#.m || #.n /*is in proper order?*/
|
||||
else MN=#.n || #.m /*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. */
|
||||
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───────────────────────────────────*/
|
||||
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.*/
|
||||
return space(hay,0) /*remove blanks from hay*/
|
||||
/*──────────────────────────────────S subroutine──────────────────────────────*/
|
||||
s: if arg(1)==1 then return arg(3);return word(arg(2) 's',1) /*pluralizer.*/
|
||||
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. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue