Teacup rim text

From Rosetta Code
Teacup rim text is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

On a set of coasters we have, there's a picture of a teacup. On the rim of the teacup the word "TEA" appears a number of times separated by bullet characters. It occurred to me that if the bullet were removed and the words run together, you could start at any letter and still end up with a meaningful three-letter word. So start at the "T" and read "TEA". Start at the "E" and read "EAT", or start at the "A" and read "ATE".

That got me thinking that maybe there are other words that could be used rather that "TEA". And that's just English. What about Italian or Greek or ... um ... Telugu.

So here's the task: from a web accessible or locally accessible word source, iterate through each word. With each word, peel off the first letter and put it at the end. Check if the word exists. If it does, keep going with the next letter, repeating the process for as many letters as there are minus one. If all of the words exist store the original word. List the words that survive the process at the end. Optionally list all their variants.

Factor

<lang factor>USING: combinators.short-circuit fry grouping hash-sets http.client kernel make math prettyprint sequences sequences.extras sets sorting splitting unicode ;

"https://raw.githubusercontent.com/dwyl/english-words/master/words.txt" http-get nip "\n" split harvest [ { [ length 2 > ] [ [ letter? ] all? ] [ all-equal? not ] } 1&& ] filter  ! we want lowercase words with > 2 [ >hash-set ] [ ] bi  ! letters which are not all the same. [ [ all-rotations members swap dupd '[ _ in? ] all? [ , ] [ drop ] if ] with each ] { } make [ natural-sort ] map members .</lang>

Output:
{
    { "arar" "rara" }
    { "ary" "rya" "yar" }
    { "ate" "eat" "tea" }
    { "eth" "het" "the" }
}


Julia

Using the MIT 10000 word list, and excluding words of less than three letters, to reduce output length. <lang julia>using HTTP

function getwords()

   req = HTTP.request("GET", "https://www.mit.edu/~ecprice/wordlist.10000")
   Dict{String, Int}((string(x), 1) for x in split(String(req.body), r"\s+"))

end

rotate(s, n) = String(circshift(Vector{UInt8}(s), n))

isliketea(w, d) = (n = length(w); n > 2 && all(i -> haskey(d, rotate(w, i)), 1:n-1))

function getteawords()

   wordlistdict = getwords()
   for word in collect(keys(wordlistdict))
       if isliketea(word, wordlistdict)
           println(word, ": ", [rotate(word, i) for i in 1:length(word)-1])
       end
   end

end

getteawords()

</lang>

Output:
pas: ["spa", "asp"]
xxx: ["xxx", "xxx"]
iii: ["iii", "iii"]
asp: ["pas", "spa"]
tea: ["ate", "eat"]
spa: ["asp", "pas"]
ate: ["eat", "tea"]
aim: ["mai", "ima"]
aaa: ["aaa", "aaa"]
car: ["rca", "arc"]
ooo: ["ooo", "ooo"]
sip: ["psi", "ips"]
arc: ["car", "rca"]
ips: ["sip", "psi"]
www: ["www", "www"]
mai: ["ima", "aim"]
rca: ["arc", "car"]
eat: ["tea", "ate"]
psi: ["ips", "sip"]
ima: ["aim", "mai"]

Perl 6

Works with: Rakudo version 2019.07.1

Using the same file as the reference implementation (Lychen), downloaded to a local file to give my connection a break.

There doesn't seem to be any restriction that the word needs to consist only of lowercase letters, so words of any case are included. Since the example code specifically shows the example words (TEA, EAT, ATE) in uppercase, I elected to uppercase the found words. Most of them are anyway, as this list seems to be full of abbreviations, acronyms and inialisms. Ah well. I didn't choose the word list.


<lang perl6>my %words; './words.txt'.IO.slurp.words.map: { %words{.lc.comb.sort.join}.push: $_ };

for %words.keys { %words{$_}:delete if %words{$_}.elems < 2 or $_.chars < 3 };

my @teacups;

for %words.values -> @these {

   my $maybe = @these[0].uc;
   my @print;
   for ^$maybe.chars {
       if $maybe ∈ @these».uc {
           @print.push: $maybe;
           $maybe = $maybe.comb.list.rotate.join;
       } else {
           @print = ();
           last
       }
   }
   @teacups.push: @print;

}

say .unique.join(", ") if .elems for sort @teacups;</lang>

Output:
AAE, AEA, EAA
AAF, AFA, FAA
AAH, AHA, HAA
AAM, AMA, MAA
AAS, ASA, SAA
ABB, BBA, BAB
ABD, BDA, DAB
ABI, BIA, IAB
ABL, BLA, LAB
ABM, BMA, MAB
ABR, BRA, RAB
ABS, BSA, SAB
ABV, BVA, VAB
ACC, CCA, CAC
ACD, CDA, DAC
ACF, CFA, FAC
ACH, CHA, HAC
ACM, CMA, MAC
ACP, CPA, PAC
ACS, CSA, SAC
ACT, CTA, TAC
ACV, CVA, VAC
ACW, CWA, WAC
ADAD, DADA
ADAR, DARA, ARAD, RADA
ADD, DDA, DAD
ADE, DEA, EAD
ADF, DFA, FAD
ADI, DIA, IAD
ADM, DMA, MAD
ADN, DNA, NAD
ADO, DOA, OAD
ADP, DPA, PAD
ADS, DSA, SAD
AER, ERA, RAE
AES, ESA, SAE
AET, ETA, TAE
AFI, FIA, IAF
AFL, FLA, LAF
AFR, FRA, RAF
AGAG, GAGA
AGC, GCA, CAG
AGD, GDA, DAG
AGH, GHA, HAG
AGR, GRA, RAG
AGS, GSA, SAG
AGT, GTA, TAG
AHI, HIA, IAH
AIC, ICA, CAI
AIL, ILA, LAI
AIM, IMA, MAI
AIR, IRA, RAI
AIS, ISA, SAI
AIT, ITA, TAI
AKE, KEA, EAK
AKH, KHA, HAK
AKO, KOA, OAK
ALE, LEA, EAL
ALIT, LITA, ITAL, TALI
ALT, LTA, TAL
AMAN, MANA, ANAM, NAMA
AMAR, MARA, ARAM, RAMA
AME, MEA, EAM
AMEN, MENA, ENAM, NAME
AMO, MOA, OAM
AMOR, MORA, ORAM, RAMO
AMP, MPA, PAM
AMR, MRA, RAM
AMS, MSA, SAM
AMT, MTA, TAM
AMU, MUA, UAM
ANAN, NANA
ANC, NCA, CAN
ANE, NEA, EAN
ANH, NHA, HAN
ANS, NSA, SAN
AOP, OPA, PAO
AOR, ORA, RAO
AOS, OSA, SAO
APG, PGA, GAP
APH, PHA, HAP
APP, PPA, PAP
APR, PRA, RAP
APS, PSA, SAP
APT, PTA, TAP
ARAR, RARA
ARAS, RASA, ASAR, SARA
ARC, RCA, CAR
ARD, RDA, DAR
ARN, RNA, NAR
ARS, RSA, SAR
ART, RTA, TAR
ARU, RUA, UAR
ASK, SKA, KAS
ASS, SSA, SAS
AST, STA, TAS
ASW, SWA, WAS
ATO, TOA, OAT
ATV, TVA, VAT
AUD, UDA, DAU
AVG, VGA, GAV
AYH, YHA, HAY
AYM, YMA, MAY
BCR, CRB, RBC
BCS, CSB, SBC
BDT, DTB, TBD
BER, ERB, RBE
BES, ESB, SBE
BID, IDB, DBI
BLL, LLB, LBL
BLO, LOB, OBL
BMG, MGB, GBM
BMP, MPB, PBM
BOO, OOB, OBO
BOT, OTB, TBO
BSS, SSB, SBS
BST, STB, TBS
BSW, SWB, WBS
BUS, USB, SBU
BYO, YOB, OBY
CCD, CDC, DCC
CCF, CFC, FCC
CCI, CIC, ICC
CCM, CMC, MCC
CCP, CPC, PCC
CCR, CRC, RCC
CCS, CSC, SCC
CCT, CTC, TCC
CCW, CWC, WCC
CDI, DIC, ICD
CDN, DNC, NCD
CDO, DOC, OCD
CDS, DSC, SCD
CDU, DUC, UCD
CED, EDC, DCE
CEE, EEC, ECE
CEN, ENC, NCE
CFM, FMC, MCF
CFP, FPC, PCF
CFR, FRC, RCF
CGM, GMC, MCG
CHI, HIC, ICH
CHM, HMC, MCH
CHO, HOC, OCH
CHS, HSC, SCH
CIM, IMC, MCI
CIO, IOC, OCI
CIP, IPC, PCI
CIR, IRC, RCI
CIS, ISC, SCI
CLE, LEC, ECL
CLR, LRC, RCL
CLU, LUC, UCL
CMD, MDC, DCM
CML, MLC, LCM
CMS, MSC, SCM
CMT, MTC, TCM
CNM, NMC, MCN
CNR, NRC, RCN
COP, OPC, PCO
COR, ORC, RCO
COS, OSC, SCO
CPL, PLC, LCP
CPM, PMC, MCP
CPR, PRC, RCP
CPS, PSC, SCP
CRE, REC, ECR
CRS, RSC, SCR
CRT, RTC, TCR
CRU, RUC, UCR
CSE, SEC, ECS
CSS, SSC, SCS
CST, STC, TCS
CTF, TFC, FCT
CTG, TGC, GCT
CTT, TTC, TCT
CUE, UEC, ECU
DDE, DED, EDD
DDS, DSD, SDD
DDT, DTD, TDD
DEN, END, NDE
DENI, ENID, NIDE, IDEN
DEP, EPD, PDE
DET, ETD, TDE
DFI, FID, IDF
DIM, IMD, MDI
DIN, IND, NDI
DIT, ITD, TDI
DIU, IUD, UDI
DLL, LLD, LDL
DLS, LSD, SDL
DMS, MSD, SDM
DMT, MTD, TDM
DMV, MVD, VDM
DOE, OED, EDO
DOI, OID, IDO
DOS, OSD, SDO
DOU, OUD, UDO
DPP, PPD, PDP
DRU, RUD, UDR
DSS, SSD, SDS
DSU, SUD, UDS
EEK, EKE, KEE
EEL, ELE, LEE
EEM, EME, MEE
EEN, ENE, NEE
EER, ERE, REE
EFT, FTE, TEF
EGOR, GORE, OREG, REGO
EGP, GPE, PEG
EHF, HFE, FEH
EHR, HRE, REH
EIN, INE, NEI
EIR, IRE, REI
EIS, ISE, SEI
ELM, LME, MEL
ELS, LSE, SEL
EMM, MME, MEM
EMP, MPE, PEM
EMR, MRE, REM
EMS, MSE, SEM
ENS, NSE, SEN
EOM, OME, MEO
EPP, PPE, PEP
EPS, PSE, SEP
ERF, RFE, FER
ERL, RLE, LER
ERS, RSE, SER
ERT, RTE, TER
ESH, SHE, HES
ESS, SSE, SES
EST, STE, TES
ETH, THE, HET
ETY, TYE, YET
EYN, YNE, NEY
FMS, MSF, SFM
FOO, OOF, OFO
FOS, OSF, SFO
FOU, OUF, UFO
FRT, RTF, TFR
FSH, SHF, HFS
FSU, SUF, UFS
GON, ONG, NGO
GPS, PSG, SGP
HIN, INH, NHI
HIP, IPH, PHI
HIS, ISH, SHI
HMP, MPH, PHM
HMS, MSH, SHM
HMT, MTH, THM
HOO, OOH, OHO
HOP, OPH, PHO
HRS, RSH, SHR
HSU, SUH, UHS
ILO, LOI, OIL
ILS, LSI, SIL
IMS, MSI, SIM
IMT, MTI, TIM
IOR, ORI, RIO
IPR, PRI, RIP
IPS, PSI, SIP
IPT, PTI, TIP
IRM, RMI, MIR
ISIS, SISI
ISS, SSI, SIS
IST, STI, TIS
ITU, TUI, UIT
IXM, XMI, MIX
KTS, TSK, SKT
LLP, LPL, PLL
LOT, OTL, TLO
LPP, PPL, PLP
LPS, PSL, SLP
LRS, RSL, SLR
LSM, SML, MLS
MMS, MSM, SMM
MMU, MUM, UMM
MOP, OPM, PMO
MOT, OTM, TMO
MPS, PSM, SMP
MRS, RSM, SMR
MSS, SSM, SMS
MST, STM, TMS
MTU, TUM, UMT
NOO, OON, ONO
NPP, PPN, PNP
NSU, SUN, UNS
OOS, OSO, SOO
OOT, OTO, TOO
OPS, PSO, SOP
OPT, PTO, TOP
OSS, SSO, SOS
OUS, USO, SOU
PPS, PSP, SPP
PSS, SSP, SPS
PST, STP, TPS
PSU, SUP, UPS
PTT, TTP, TPT
RSS, SSR, SRS
RSU, SUR, URS
RSV, SVR, VRS
SST, STS, TSS
SSU, SUS, USS
YSO, SOY, OYS

Lychen

Lychen is V8 JavaScript wrapped in C#, exposing C# into JavaScript.

<lang javascript> const wc = new CS.System.Net.WebClient(); const lines = wc.DownloadString("https://raw.githubusercontent.com/dwyl/english-words/master/words.txt"); const words = lines.split(/\n/g); const collection = {}; words.filter(word => word.length > 2).forEach(word => {

 const theword = word.toLowerCase();
 let allok = true;
 let newword = theword;
 for (let i = 0; i < word.length - 1; i++) {
   newword = newword.substr(1) + newword.substr(0, 1);
   if (!words.includes(newword)) {
     allok = false;
     break;
   }
 }
 if (allok) {
   var key = theword.split("").sort().join("");
   if (!collection[key]) {
     collection[key] = [theword];
   } else {
     if (!collections[key].includes(theword)) {
       collection[key].push(theword);
     }
   }
 }

}); Object.keys(collection) .filter(key => collection[key].length > 1) .forEach(key => console.log("%s", collection[key].join(", "))); </lang>

arar, rara
ary, yar, rya
ate, eat, tea
eth, het, the, the