Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Abbreviations,_automatic

View file

@ -0,0 +1,137 @@
The use of   abbreviations   (also sometimes called synonyms, nicknames, AKAs, or aliases)   can be an
<br>easy way to add flexibility when specifying or using commands, sub─commands, options, etc.
<!--
(AKA = also known as)
!-->
It would make a list of words easier to maintain &nbsp; (as words are added, changed, and/or deleted) &nbsp; if
the minimum abbreviation length of that list could be automatically (programmatically) determined.
For this task, use the list (below) of the days-of-the-week names that are expressed in about a hundred languages &nbsp; (note that there is a blank line in the list).
<pre style="height:45ex">
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
Sondag Maandag Dinsdag Woensdag Donderdag Vrydag Saterdag
E_djelë E_hënë E_martë E_mërkurë E_enjte E_premte E_shtunë
Ehud Segno Maksegno Erob Hamus Arbe Kedame
Al_Ahad Al_Ithinin Al_Tholatha'a Al_Arbia'a Al_Kamis Al_Gomia'a Al_Sabit
Guiragui Yergou_shapti Yerek_shapti Tchorek_shapti Hink_shapti Ourpat Shapat
domingu llunes martes miércoles xueves vienres sábadu
Bazar_gÜnÜ Birinci_gÜn Çkinci_gÜn ÜçÜncÜ_gÜn DÖrdÜncÜ_gÜn Bes,inci_gÜn Altòncò_gÜn
Igande Astelehen Astearte Asteazken Ostegun Ostiral Larunbat
Robi_bar Shom_bar Mongal_bar Budhh_bar BRihashpati_bar Shukro_bar Shoni_bar
Nedjelja Ponedeljak Utorak Srijeda Cxetvrtak Petak Subota
Disul Dilun Dimeurzh Dimerc'her Diriaou Digwener Disadorn
nedelia ponedelnik vtornik sriada chetvartak petak sabota
sing_kei_yaht sing_kei_yat sing_kei_yee sing_kei_saam sing_kei_sie sing_kei_ng sing_kei_luk
Diumenge Dilluns Dimarts Dimecres Dijous Divendres Dissabte
Dzeenkk-eh Dzeehn_kk-ehreh Dzeehn_kk-ehreh_nah_kay_dzeeneh Tah_neesee_dzeehn_neh Deehn_ghee_dzee-neh Tl-oowey_tts-el_dehlee Dzeentt-ahzee
dy_Sul dy_Lun dy_Meurth dy_Mergher dy_You dy_Gwener dy_Sadorn
Dimanch Lendi Madi Mèkredi Jedi Vandredi Samdi
nedjelja ponedjeljak utorak srijeda cxetvrtak petak subota
nede^le ponde^lí úterÿ str^eda c^tvrtek pátek sobota
Sondee Mondee Tiisiday Walansedee TOOsedee Feraadee Satadee
s0ndag mandag tirsdag onsdag torsdag fredag l0rdag
zondag maandag dinsdag woensdag donderdag vrijdag zaterdag
Diman^co Lundo Mardo Merkredo ^Jaùdo Vendredo Sabato
pÜhapäev esmaspäev teisipäev kolmapäev neljapäev reede laupäev
Diu_prima Diu_sequima Diu_tritima Diu_quartima Diu_quintima Diu_sextima Diu_sabbata
sunnudagur mánadagur tÿsdaguy mikudagur hósdagur friggjadagur leygardagur
Yek_Sham'beh Do_Sham'beh Seh_Sham'beh Cha'har_Sham'beh Panj_Sham'beh Jom'eh Sham'beh
sunnuntai maanantai tiistai keskiviiko torsktai perjantai lauantai
dimanche lundi mardi mercredi jeudi vendredi samedi
Snein Moandei Tiisdei Woansdei Tonersdei Freed Sneon
Domingo Segunda_feira Martes Mércores Joves Venres Sábado
k'vira orshabati samshabati otkhshabati khutshabati p'arask'evi shabati
Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag
Kiriaki' Defte'ra Tri'ti Teta'rti Pe'mpti Paraskebi' Sa'bato
ravivaar somvaar mangalvaar budhvaar guruvaar shukravaar shanivaar
pópule pó`akahi pó`alua pó`akolu pó`ahá pó`alima pó`aono
Yom_rishon Yom_sheni Yom_shlishi Yom_revi'i Yom_chamishi Yom_shishi Shabat
ravivara somavar mangalavar budhavara brahaspativar shukravara shanivar
vasárnap hétfö kedd szerda csütörtök péntek szombat
Sunnudagur Mánudagur ╞riδjudagur Miδvikudagar Fimmtudagur FÖstudagur Laugardagur
sundio lundio mardio merkurdio jovdio venerdio saturdio
Minggu Senin Selasa Rabu Kamis Jumat Sabtu
Dominica Lunedi Martedi Mercuridi Jovedi Venerdi Sabbato
Dé_Domhnaigh Dé_Luain Dé_Máirt Dé_Ceadaoin Dé_ardaoin Dé_hAoine Dé_Sathairn
domenica lunedí martedí mercoledí giovedí venerdí sabato
Nichiyou_bi Getzuyou_bi Kayou_bi Suiyou_bi Mokuyou_bi Kin'you_bi Doyou_bi
Il-yo-il Wol-yo-il Hwa-yo-il Su-yo-il Mok-yo-il Kum-yo-il To-yo-il
Dies_Dominica Dies_Lunæ Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Saturni
sve-tdien pirmdien otrdien tresvdien ceturtdien piektdien sestdien
Sekmadienis Pirmadienis Antradienis Trec^iadienis Ketvirtadienis Penktadienis S^es^tadienis
Wangu Kazooba Walumbe Mukasa Kiwanuka Nnagawonye Wamunyi
xing-_qi-_rì xing-_qi-_yi-. xing-_qi-_èr xing-_qi-_san-. xing-_qi-_sì xing-_qi-_wuv. xing-_qi-_liù
Jedoonee Jelune Jemayrt Jecrean Jardaim Jeheiney Jesam
Jabot Manre Juje Wonje Taije Balaire Jarere
geminrongo minòmishi mártes mièrkoles misheushi bèrnashi mishábaro
Ahad Isnin Selasa Rabu Khamis Jumaat Sabtu
sφndag mandag tirsdag onsdag torsdag fredag lφrdag
lo_dimenge lo_diluns lo_dimarç lo_dimèrcres lo_dijòus lo_divendres lo_dissabte
djadomingo djaluna djamars djarason djaweps djabièrna djasabra
Niedziela Poniedzial/ek Wtorek S,roda Czwartek Pia,tek Sobota
Domingo segunda-feire terça-feire quarta-feire quinta-feire sexta-feira såbado
Domingo Lunes martes Miercoles Jueves Viernes Sabado
Duminicª Luni Mart'i Miercuri Joi Vineri Sâmbªtª
voskresenie ponedelnik vtornik sreda chetverg pyatnitsa subbota
Sunday Di-luain Di-màirt Di-ciadain Di-ardaoin Di-haoine Di-sathurne
nedjelja ponedjeljak utorak sreda cxetvrtak petak subota
Sontaha Mmantaha Labobedi Laboraro Labone Labohlano Moqebelo
Iridha- Sandhudha- Anga.haruwa-dha- Badha-dha- Brahaspa.thindha- Sikura-dha- Sena.sura-dha-
nedel^a pondelok utorok streda s^tvrtok piatok sobota
Nedelja Ponedeljek Torek Sreda Cxetrtek Petek Sobota
domingo lunes martes miércoles jueves viernes sábado
sonde mundey tude-wroko dride-wroko fode-wroko freyda Saturday
Jumapili Jumatatu Jumanne Jumatano Alhamisi Ijumaa Jumamosi
söndag måndag tisdag onsdag torsdag fredag lordag
Linggo Lunes Martes Miyerkoles Huwebes Biyernes Sabado
Lé-pài-jít Pài-it Pài-jï Pài-sañ Pài-sì Pài-gÖ. Pài-lák
wan-ar-tit wan-tjan wan-ang-kaan wan-phoet wan-pha-ru-hat-sa-boh-die wan-sook wan-sao
Tshipi Mosupologo Labobedi Laboraro Labone Labotlhano Matlhatso
Pazar Pazartesi Sali Çar,samba Per,sembe Cuma Cumartesi
nedilya ponedilok vivtorok sereda chetver pyatnytsya subota
Chu?_Nhâ.t Thú*_Hai Thú*_Ba Thú*_Tu* Thú*_Na'm Thú*_Sáu Thú*_Ba?y
dydd_Sul dyds_Llun dydd_Mawrth dyds_Mercher dydd_Iau dydd_Gwener dyds_Sadwrn
Dibeer Altine Talaata Allarba Al_xebes Aljuma Gaaw
iCawa uMvulo uLwesibini uLwesithathu uLuwesine uLwesihlanu uMgqibelo
zuntik montik dinstik mitvokh donershtik fraytik shabes
iSonto uMsombuluko uLwesibili uLwesithathu uLwesine uLwesihlanu uMgqibelo
Dies_Dominica Dies_Lunæ Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Saturni
Bazar_gÜnÜ Bazar_ærtæsi Çærs,ænbæ_axs,amò Çærs,ænbæ_gÜnÜ CÜmæ_axs,amò CÜmæ_gÜnÜ CÜmæ_Senbæ
Sun Moon Mars Mercury Jove Venus Saturn
zondag maandag dinsdag woensdag donderdag vrijdag zaterdag
KoseEraa GyoOraa BenEraa Kuoraa YOwaaraa FeEraa Memenaa
Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Sonnabend
Domingo Luns Terza_feira Corta_feira Xoves Venres Sábado
Dies_Solis Dies_Lunae Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Sabbatum
xing-_qi-_tiàn xing-_qi-_yi-. xing-_qi-_èr xing-_qi-_san-. xing-_qi-_sì xing-_qi-_wuv. xing-_qi-_liù
djadomingu djaluna djamars djarason djaweps djabièrnè djasabra
Killachau Atichau Quoyllurchau Illapachau Chaskachau Kuychichau Intichau
</pre>
''Caveat: &nbsp; The list (above) most surely contains errors (or, at the least, differences) of what the actual (or true) names for the days-of-the-week.''
To make this Rosetta Code task page as small as possible, if processing the complete list, read the days-of-the-week from a file (that is created from the above list).
Notes concerning the above list of words
::* &nbsp; each line has a list of days-of-the-week for a language, separated by at least one blank
::* &nbsp; the words on each line happen to be in order, from Sunday ──► Saturday
::* &nbsp; most lines have words in mixed case and some have all manner of accented words and other characters
::* &nbsp; some words were translated to the nearest character that was available to ''code page'' &nbsp; '''437'''
::* &nbsp; the characters in the words are not restricted except that they may not have imbedded blanks
::* &nbsp; for this example, the use of an underscore (<big>'''_'''</big>) was used to indicate a blank in a word
;Task:
::* &nbsp; The list of words &nbsp; (days of the week) &nbsp; needn't be verified/validated.
::* &nbsp; Write a function to find the (numeric) minimum length abbreviation for each line that would make abbreviations unique.
::* &nbsp; A blank line &nbsp; (or a null line) &nbsp; should return a null string.
::* &nbsp; Process and show the output for <u>at least</u> the first '''five''' lines of the file.
::* &nbsp; Show all output here.
{{Template:Strings}}
<br><br>

View file

@ -0,0 +1,22 @@
F shortest_abbreviation_length(line, list_size)
V words = line.split( )
V word_count = words.len
I word_count != list_size
X ValueError(Not enough entries, expected #. found #..format(list_size, word_count))
V abbreviation_length = 1
L
V abbreviations = Set(words.map(word -> word[0 .< @abbreviation_length]))
I abbreviations.len == list_size
R abbreviation_length
abbreviation_length++
F automatic_abbreviations(filename, words_per_line)
L(line) File(filename).read().split("\n")
I line.len > 0
V length = shortest_abbreviation_length(line, words_per_line)
print(#2 #..format(length, line))
E
print()
automatic_abbreviations(daysOfWeek.txt, 7)

View file

@ -0,0 +1,472 @@
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program abbrAuto64.s */
/* store list of day in a file listDays.txt*/
/* and run the program abbrAuto64 listDays.txt */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ BUFFERSIZE, 10000
.equ NBMAXIDAYS, 7
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessTitre: .asciz "Nom du fichier : "
szCarriageReturn: .asciz "\n"
szMessErreur: .asciz "Error detected.\n"
szMessErrBuffer: .asciz "buffer size too less !!"
szSpace: .asciz " "
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
qAdrFicName: .skip 8
iTabAdrDays: .skip 8 * NBMAXIDAYS
iTabAdrDays2: .skip 8 * NBMAXIDAYS
sBufferDays: .skip BUFFERSIZE
sBuffer: .skip BUFFERSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // INFO: main
mov x0,sp // stack address for load parameter
bl traitFic // read file and process
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsZoneConv: .quad sZoneConv
/******************************************************************/
/* read file */
/******************************************************************/
/* x0 contains address stack begin */
traitFic: // INFO: traitFic
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,fp,[sp,-16]! // save registres
mov fp,x0 // fp <- start address
ldr x4,[fp] // number of Command line arguments
cmp x4,#1
ble 99f
add x5,fp,#16 // second parameter address
ldr x5,[x5]
ldr x0,qAdrqAdrFicName
str x5,[x0]
ldr x0,qAdrszMessTitre
bl affichageMess // display string
mov x0,x5
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess // display carriage return
mov x0,AT_FDCWD
mov x1,x5 // file name
mov x2,#O_RDWR // flags
mov x3,#0 // mode
mov x8, #OPEN // call system OPEN
svc 0
cmp x0,#0 // error ?
ble 99f
mov x7,x0 // File Descriptor
ldr x1,qAdrsBufferDays // buffer address
mov x2,#BUFFERSIZE // buffer size
mov x8,#READ // read file
svc #0
cmp x0,#0 // error ?
blt 99f
// extraction datas
ldr x1,qAdrsBufferDays // buffer address
add x1,x1,x0
mov x0,#0 // store zéro final
strb w0,[x1]
ldr x0,qAdriTabAdrDays // key string command table
ldr x1,qAdrsBufferDays // buffer address
bl extracDatas
// close file
mov x0,x7
mov x8, #CLOSE
svc 0
mov x0,#0
b 100f
99: // error
ldr x0,qAdrszMessErreur // error message
bl affichageMess
mov x0,#-1
100:
ldp x8,fp,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrqAdrFicName: .quad qAdrFicName
qAdrszMessTitre: .quad szMessTitre
qAdrszMessErreur: .quad szMessErreur
qAdrsBuffer: .quad sBuffer
qAdrsBufferDays: .quad sBufferDays
qAdriTabAdrDays: .quad iTabAdrDays
/******************************************************************/
/* extrac lines file buffer */
/******************************************************************/
/* x0 contains strings address */
/* x1 contains buffer address */
extracDatas: // INFO: extracDatas
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,fp,[sp,-16]! // save registres
mov x7,x0
mov x6,x1
mov x2,#0 // string buffer indice
mov x4,x1 // start string
mov x5,#0 // string index
1:
ldrb w3,[x6,x2]
cmp w3,#0
beq 4f // end
cmp w3,#0xA
beq 2f
cmp w3,#' ' // end string
beq 3f
add x2,x2,#1
b 1b
2:
mov x3,#0
strb w3,[x6,x2]
ldrb w3,[x6,x2]
cmp w3,#0xD
bne 21f
add x2,x2,#2
b 22f
21:
add x2,x2,#1
22:
mov x0,x4 // store last day of line in table
str x4,[x7,x5,lsl #3]
mov x0,x5 // days number
bl traitLine // process a line of days
mov x5,#0 // new line
b 5f
3:
mov x3,#0
strb w3,[x6,x2]
add x2,x2,#1
4:
mov x0,x4
str x4,[x7,x5,lsl #3]
add x5,x5,#1
5: // supress spaces
ldrb w3,[x6,x2]
cmp w3,#0
beq 100f
cmp w3,#' '
cinc x2,x2,eq
beq 5b
add x4,x6,x2 // new start address
b 1b
100:
ldp x8,fp,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* processing a line */
/******************************************************************/
/* x0 contains days number in table */
traitLine: // INFO: traitLine
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
stp x12,x13,[sp,-16]! // save registres
cmp x0,#1 // one day ?
bgt 1f // no
ldr x0,qAdrszCarriageReturn // yes display empty line
bl affichageMess
b 100f
1: // line OK
mov x6,x0 // days number
ldr x0,qAdriTabAdrDays
ldr x1,qAdriTabAdrDays2
mov x2,#0
11: // copy days table into other for display final
ldr x3,[x0,x2,lsl #3]
str x3,[x1,x2,lsl #3]
add x2,x2,#1
cmp x2,x6
ble 11b
ldr x0,qAdriTabAdrDays // and sort first table
mov x1,#0
add x2,x6,#1
bl insertionSort
mov x8,#1 // abbrevations counter
ldr x12,qAdriTabAdrDays
mov x2,#0
ldr x10,[x12,x2,lsl #3] // load first sorting day
mov x11,#0
mov x3,#1
2: // begin loop
ldr x4,[x12,x3,lsl #3] // load other day
mov x0,x10 // day1
mov x1,x4 // day 2
mov x2,#0 // position 0
bl compareChar
cmp x0,#0 // first letter equal ?
beq 3f
mov x10,x4 // no -> move day 2 in day 1
b 6f
3: // if equal
mov x7,x1 // characters length (1,2,3)
mov x11,#1 // letters position
4: // loop to compare letters days
mov x0,x10
mov x1,x4
mov x2,x7
bl compareChar
cmp x0,#0
bne 5f
cmp x5,#0 // if end
beq 5f
add x7,x7,x1 // next character
add x11,x11,#1 // count letter
b 4b
5:
add x11,x11,#1 // increment letters position
cmp x11,x8 // and store if > position précedente
csel x8,x11,x8,gt
//movgt x8,x11
mov x10,x4 // and day1 = day2
6:
add x3,x3,#1 // increment day
cmp x3,x6
ble 2b // and loop
mov x0,x8 // display position letter
ldr x1,qAdrsZoneConv
bl conversion10
//mov x2,#0
//strb x2,[x1,x0]
ldr x0,qAdrsZoneConv
bl affichageMess
ldr x0,qAdrszSpace
bl affichageMess
ldr x0,qAdriTabAdrDays2 // and display list origine days
mov x1,x6
bl displayListDays
100:
ldp x12,x13,[sp],16 // restaur des 2 registres
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrszSpace: .quad szSpace
qAdriTabAdrDays2: .quad iTabAdrDays2
/******************************************************************/
/* comparison character unicode */
/******************************************************************/
/* x0 contains address first string */
/* x1 contains address second string */
/* x2 contains the character position to compare */
/* x0 return 0 if equal 1 if > -1 if < */
/* x1 return character S1 size in octet if equal */
/* x2 return character S2 size in octet */
compareChar:
stp lr,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
ldrb w3,[x0,x2]
ldrb w4,[x1,x2]
cmp w3,w4 // compare first byte
blt 3f
bgt 4f
bne 100f
and w3,w3,#0b11100000 // 3 bytes ?
cmp w3,#0b11100000
bne 1f
add x2,x2,#1
ldrb w3,[x0,x2]
ldrb w4,[x1,x2]
cmp w3,w4
blt 3f
bgt 4f
bne 100f
add x2,x2,#1
ldrb w3,[x0,x2]
ldrb w4,[x1,x2]
cmp w3,w4
blt 3f
bgt 4f
bne 100f
mov x0,#0
mov x1,#3
b 100f
1:
cmp w3,#0b11000000 // 2 bytes ?
bne 2f
add x2,x2,#1
ldrb w3,[x0,x2]
ldrb w4,[x1,x2]
cmp w3,w4
blt 3f
bgt 4f
bne 100f
mov x0,#0
mov x1,#2
b 100f
2: // 1 byte
mov x0,#0
mov x1,#1
b 100f
3:
mov x0,#-1
b 100f
4:
mov x0,#1
100:
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp lr,x3,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* control load */
/******************************************************************/
/* x0 contains string table */
/* x1 contains days number */
displayListDays:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
mov x5,x0
mov x2,#0
1:
cmp x2,x1
bgt 2f
ldr x0,[x5,x2,lsl #3]
bl affichageMess
ldr x0,qAdrszSpace
bl affichageMess
add x2,x2,#1
b 1b
2:
ldr x0,qAdrszCarriageReturn
bl affichageMess
100:
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/************************************/
/* Strings case sensitive comparisons */
/************************************/
/* x0 et x1 contains the address of strings */
/* return 0 in x0 if equals */
/* return -1 if string x0 < string x1 */
/* return 1 if string x0 > string x1 */
comparStrings:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
mov x2,#0 // counter
1:
ldrb w3,[x0,x2] // byte string 1
ldrb w4,[x1,x2] // byte string 2
cmp w3,w4
blt 2f
bgt 3f
bne 100f // not equals
cmp w3,#0 // 0 end string
beq 4f // end string
add x2,x2,#1 // else add 1 in counter
b 1b // and loop
2:
mov x0,#-1 // small
b 100f
3:
mov x0,#1 // greather
b 100f
4:
mov x0,#0 // equal
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* insertion sort */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the first element */
/* x2 contains the number of element */
insertionSort:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
mov x6,x0
add x3,x1,#1 // start index i
1: // start loop
ldr x1,[x6,x3,lsl #3] // load value A[i]
sub x5,x3,#1 // index j
2:
ldr x4,[x6,x5,lsl #3] // load value A[j]
mov x0,x4
bl comparStrings
cmp x0,#1 // compare value
bne 3f
add x5,x5,#1 // increment index j
str x4,[x6,x5,lsl #3] // store value A[j+1]
subs x5,x5,#2 // j = j - 1
bge 2b // loop if j >= 0
3:
add x5,x5,#1 // increment index j
str x1,[x6,x5,lsl #3] // store value A[i] in A[j+1]
add x3,x3,#1 // increment index i
cmp x3,x2 // end ?
blt 1b // no -> loop
100:
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"

View file

@ -0,0 +1,420 @@
/* ARM assembly Raspberry PI */
/* program abbrAuto.s */
/* store list of day in a file listDays.txt*/
/* and run the program abbrAuto listDays.txt */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ STDIN, 0 @ Linux input console
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ READ, 3 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
.equ OPEN, 5 @ Linux syscall
.equ CLOSE, 6 @ Linux syscall
.equ O_RDWR, 0x0002 @ open for reading and writing
.equ BUFFERSIZE, 10000
.equ NBMAXIDAYS, 7
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessTitre: .asciz "Nom du fichier : "
szCarriageReturn: .asciz "\n"
szMessErreur: .asciz "Error detected.\n"
szMessErrBuffer: .asciz "buffer size too less !!"
szSpace: .asciz " "
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
iAdrFicName: .skip 4
iTabAdrDays: .skip 4 * NBMAXIDAYS
iTabAdrDays2: .skip 4 * NBMAXIDAYS
sBufferDays: .skip BUFFERSIZE
sBuffer: .skip BUFFERSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ INFO: main
mov r0,sp @ stack address for load parameter
bl traitFic @ read file and process
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
//iAdrszMessErrBuffer: .int szMessErrBuffer
iAdrsZoneConv: .int sZoneConv
/******************************************************************/
/* read file */
/******************************************************************/
/* r0 contains address stack begin */
traitFic: @ INFO: traitFic
push {r1-r8,fp,lr} @ save registers
mov fp,r0 @ fp <- start address
ldr r4,[fp] @ number of Command line arguments
cmp r4,#1
movle r0,#-1
ble 99f
add r5,fp,#8 @ second parameter address
ldr r5,[r5]
ldr r0,iAdriAdrFicName
str r5,[r0]
ldr r0,iAdrszMessTitre
bl affichageMess @ display string
mov r0,r5
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess @ display carriage return
mov r0,r5 @ file name
mov r1,#O_RDWR @ flags
mov r2,#0 @ mode
mov r7, #OPEN @ call system OPEN
svc 0
cmp r0,#0 @ error ?
ble 99f
mov r8,r0 @ File Descriptor
ldr r1,iAdrsBufferDays @ buffer address
mov r2,#BUFFERSIZE @ buffer size
mov r7,#READ @ read file
svc #0
cmp r0,#0 @ error ?
blt 99f
@ extraction datas
ldr r1,iAdrsBufferDays @ buffer address
add r1,r0
mov r0,#0 @ store zéro final
strb r0,[r1]
ldr r0,iAdriTabAdrDays @ key string command table
ldr r1,iAdrsBufferDays @ buffer address
bl extracDatas
@ close file
mov r0,r8
mov r7, #CLOSE
svc 0
mov r0,#0
b 100f
99: @ error
ldr r1,iAdrszMessErreur @ error message
bl displayError
mov r0,#-1
100:
pop {r1-r8,fp,lr} @ restaur registers
bx lr @return
iAdriAdrFicName: .int iAdrFicName
iAdrszMessTitre: .int szMessTitre
iAdrszMessErreur: .int szMessErreur
iAdrsBuffer: .int sBuffer
iAdrsBufferDays: .int sBufferDays
iAdriTabAdrDays: .int iTabAdrDays
/******************************************************************/
/* extrac lines file buffer */
/******************************************************************/
/* r0 contains strings address */
/* r1 contains buffer address */
extracDatas: @ INFO: extracDatas
push {r1-r8,lr} @ save registers
mov r7,r0
mov r6,r1
mov r2,#0 @ string buffer indice
mov r4,r1 @ start string
mov r5,#0 @ string index
1:
ldrb r3,[r6,r2]
cmp r3,#0
beq 4f @ end
cmp r3,#0xA
beq 2f
cmp r3,#' ' @ end string
beq 3f
add r2,#1
b 1b
2:
mov r3,#0
strb r3,[r6,r2]
ldrb r3,[r6,r2]
cmp r3,#0xD
addeq r2,#2
addne r2,#1
mov r0,r4 @ store last day of line in table
str r4,[r7,r5,lsl #2]
mov r0,r5 @ days number
bl traitLine @ process a line of days
mov r5,#0 @ new line
b 5f
3:
mov r3,#0
strb r3,[r6,r2]
add r2,#1
4:
mov r0,r4
str r4,[r7,r5,lsl #2]
add r5,#1
5: @ supress spaces
ldrb r3,[r6,r2]
cmp r3,#0
beq 100f
cmp r3,#' '
addeq r2,r2,#1
beq 5b
add r4,r6,r2 @ new start address
b 1b
100:
pop {r1-r8,lr} @ restaur registers
bx lr @return
/******************************************************************/
/* processing a line */
/******************************************************************/
/* r0 contains days number in table */
traitLine: @ INFO: traitLine
push {r1-r12,lr} @ save register
cmp r0,#1 @ one day ?
bgt 1f @ no
ldr r0,iAdrszCarriageReturn @ yes display empty line
bl affichageMess
b 100f
1: @ line OK
mov r6,r0 @ days number
ldr r0,iAdriTabAdrDays
ldr r1,iAdriTabAdrDays2
mov r2,#0
11: @ copy days table into other for display final
ldr r3,[r0,r2,lsl #2]
str r3,[r1,r2,lsl #2]
add r2,#1
cmp r2,r6
ble 11b
ldr r0,iAdriTabAdrDays @ and sort first table
mov r1,#0
add r2,r6,#1
bl insertionSort
mov r8,#1 @ abbrevations counter
ldr r12,iAdriTabAdrDays
mov r2,#0
ldr r10,[r12,r2,lsl #2] @ load first sorting day
mov r11,#0
mov r3,#1
2: @ begin loop
ldr r4,[r12,r3,lsl #2] @ load other day
@ 1er lettre identique
mov r0,r10 @ day1
mov r1,r4 @ day 2
mov r2,#0 @ position 0
bl compareChar
cmp r0,#0 @ first letter equal ?
movne r10,r4 @ no -> move day 2 in day 1
bne 6f
3: @ if equal
mov r7,r1 @ characters length (1,2,3)
mov r11,#1 @ letters position
4: @ loop to compare letters days
mov r0,r10
mov r1,r4
mov r2,r7
bl compareChar
cmp r0,#0
bne 5f
cmp r5,#0 @ if end
beq 5f
add r7,r7,r1 @ next character
add r11,r11,#1 @ count letter
b 4b
5:
add r11,r11,#1 @ increment letters position
cmp r11,r8 @ and store if > position précedente
movgt r8,r11
mov r10,r4 @ and day1 = day2
6:
add r3,r3,#1 @ increment day
cmp r3,r6
ble 2b @ and loop
mov r0,r8 @ display position letter
ldr r1,iAdrsZoneConv
bl conversion10
mov r2,#0
strb r2,[r1,r0]
ldr r0,iAdrsZoneConv
bl affichageMess
ldr r0,iAdrszSpace
bl affichageMess
ldr r0,iAdriTabAdrDays2 @ and display list origine days
mov r1,r6
bl displayListDays
100:
pop {r1-r12,lr} @ restaur registers
bx lr @return
iAdrszSpace: .int szSpace
iAdriTabAdrDays2: .int iTabAdrDays2
/******************************************************************/
/* comparison character unicode */
/******************************************************************/
/* r0 contains address first string */
/* r1 contains address second string */
/* r2 contains the character position to compare */
/* r0 return 0 if equal 1 if > -1 if < */
/* r1 return character S1 size in octet if equal */
/* r2 return character S2 size in octet */
compareChar:
push {r3-r8,lr} @ save registers
ldrb r3,[r0,r2]
ldrb r4,[r1,r2]
cmp r3,r4 @ compare first byte
movlt r0,#-1
movgt r0,#1
bne 100f
and r3,#0b11100000 @ 3 bytes ?
cmp r3,#0b11100000
bne 1f
add r2,#1
ldrb r3,[r0,r2]
ldrb r4,[r1,r2]
cmp r3,r4
movlt r0,#-1
movgt r0,#1
bne 100f
add r2,#1
ldrb r3,[r0,r2]
ldrb r4,[r1,r2]
cmp r3,r4
movlt r0,#-1
movgt r0,#1
bne 100f
mov r0,#0
mov r1,#3
b 100f
1:
and r3,#0b11100000 @ 2 bytes ?
cmp r3,#0b11000000
bne 2f
add r2,#1
ldrb r3,[r0,r2]
ldrb r4,[r1,r2]
cmp r3,r4
movlt r0,#-1
movgt r0,#1
bne 100f
mov r0,#0
mov r1,#2
b 100f
2: @ 1 byte
mov r0,#0
mov r1,#1
100:
pop {r3-r8,lr} @ restaur registers
bx lr @return
/******************************************************************/
/* control load */
/******************************************************************/
/* r0 contains string table */
/* r1 contains days number */
displayListDays:
push {r1-r8,lr} @ save registers
mov r5,r0
mov r2,#0
1:
cmp r2,r1
bgt 2f
ldr r0,[r5,r2,lsl #2]
bl affichageMess
ldr r0,iAdrszSpace
bl affichageMess
add r2,r2,#1
b 1b
2:
ldr r0,iAdrszCarriageReturn
bl affichageMess
100:
pop {r1-r8,lr} @ restaur registers
bx lr @return
/************************************/
/* Strings case sensitive comparisons */
/************************************/
/* r0 et r1 contains the address of strings */
/* return 0 in r0 if equals */
/* return -1 if string r0 < string r1 */
/* return 1 if string r0 > string r1 */
comparStrings:
push {r1-r4} @ save des registres
mov r2,#0 @ counter
1:
ldrb r3,[r0,r2] @ byte string 1
ldrb r4,[r1,r2] @ byte string 2
cmp r3,r4
movlt r0,#-1 @ small
movgt r0,#1 @ greather
bne 100f @ not equals
cmp r3,#0 @ 0 end string
moveq r0,#0 @ equal
beq 100f @ end string
add r2,r2,#1 @ else add 1 in counter
b 1b @ and loop
100:
pop {r1-r4}
bx lr
/******************************************************************/
/* insertion sort */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the first element */
/* r2 contains the number of element */
insertionSort:
push {r1-r6,lr} @ save registers
mov r6,r0
add r3,r1,#1 @ start index i
1: @ start loop
ldr r1,[r6,r3,lsl #2] @ load value A[i]
sub r5,r3,#1 @ index j
2:
ldr r4,[r6,r5,lsl #2] @ load value A[j]
mov r0,r4
bl comparStrings
cmp r0,#1 @ compare value
bne 3f
add r5,#1 @ increment index j
str r4,[r6,r5,lsl #2] @ store value A[j+1]
subs r5,#2 @ j = j - 1
bge 2b @ loop if j >= 0
3:
add r5,#1 @ increment index j
str r1,[r6,r5,lsl #2] @ store value A[i] in A[j+1]
add r3,#1 @ increment index i
cmp r3,r2 @ end ?
blt 1b @ no -> loop
100:
pop {r1-r6,lr}
bx lr
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"

View file

@ -0,0 +1,30 @@
# syntax: GAWK -f ABBREVIATIONS_AUTOMATIC.AWK ABBREVIATIONS_AUTOMATIC.TXT
{ dow_arr[NR] = $0 }
END {
for (i=1; i<=NR; i++) {
if (split(dow_arr[i],arr1,FS) != 7) {
printf("NG %s\n",dow_arr[i])
continue
}
col_width = 0
for (j=1; j<=7; j++) {
col_width = max(col_width,length(arr1[j]))
}
for (col=1; col<=col_width; col++) {
delete arr2
for (j=1; j<=7; j++) {
arr2[toupper(substr(arr1[j],1,col))]
}
if (length(arr2) == 7) {
break
}
if (col >= col_width) { # catches duplicate day names
col = "NG"
break
}
}
printf("%2s %s\n",col,dow_arr[i])
}
exit(0)
}
function max(x,y) { return((x > y) ? x : y) }

View file

@ -0,0 +1,71 @@
with Ada.Containers.Indefinite_Vectors;
with Ada.Strings.Fixed;
with Ada.Strings.Maps;
with Ada.Text_IO;
procedure Abbreviations is
package String_Vectors is
new Ada.Containers.Indefinite_Vectors (Index_Type => Positive,
Element_Type => String);
use Ada.Text_IO, String_Vectors;
function Split (Line : String) return Vector is
Result : Vector;
First : Natural;
Last : Natural := Line'First - 1;
begin
while Last + 1 in Line'Range loop
Ada.Strings.Fixed.Find_Token
(Line, Ada.Strings.Maps.To_Set (" "), Last + 1,
Ada.Strings.Outside, First, Last);
exit when Last = 0;
Append (Result, Line (First .. Last));
end loop;
return Result;
end Split;
function Abbrev_Length (Items : Vector) return Natural is
use type Ada.Containers.Count_Type;
Max : Natural := 0;
Abbrevs : Vector;
begin
for Item of Items loop
Max := Natural'Max (Max, Item'Length);
end loop;
for Length in 1 .. Max loop
Abbrevs := Empty_Vector;
for Item of Items loop
declare
Last : constant Natural
:= Natural'Min (Item'Last, Item'First + Length - 1);
Abbrev : String renames Item (Item'First .. Last);
begin
exit when Abbrevs.Contains (Abbrev);
Abbrevs.Append (Abbrev);
end;
end loop;
if Abbrevs.Length = Items.Length then
return Length;
end if;
end loop;
return 0;
end Abbrev_Length;
procedure Process (Line : String) is
package Natural_IO is new Ada.Text_IO.Integer_IO (Natural);
Words : constant Vector := Split (Line);
Length : constant Natural := Abbrev_Length (Words);
begin
Natural_IO.Put (Length, Width => 2);
Put (" ");
Put_Line (Line);
end Process;
begin
while not End_Of_File loop
Process (Get_Line);
end loop;
end Abbreviations;

View file

@ -0,0 +1,28 @@
#include <jambo.h>
#define MAX_LINE 150
Main
Break on
days of week = 0, fd=0, length=0, days=0, temp=0
Open in("dias_de_la_semana.txt")( fd )
If ( Not( File error ) )
Loop if (Not (Eof(fd)) )
Using( MAX_LINE ), Split( Readlin(fd) » (days), days of week, " ")
Continue if( Zero( Length( days of week ) » (length) ) )
i=1
Loop
Let( temp := Ucase(Left( i, days of week )))
aSort(temp)
Break if ( Eq(Length(Unique(temp)), length ) )
++i
Back
Printnl( Cpad(" ",3,Str(i))," : ", Utf8(Ansi(days)) )
Back
Close(fd)
Else
Printnl("Error en archivo: ", ~Get str file error)
End If
End

View file

@ -0,0 +1,22 @@
AutoAbbreviations(line){
len := prev := 0
Days := StrSplit(line, " ")
loop % StrLen(Days.1)
{
obj := []
for j, day in Days
{
abb := SubStr(day, 1, len)
obj[abb] := (obj[abb] ? obj[abb] : 0) + 1
if (obj[abb] > 1)
{
len++
break
}
}
if (prev = len)
break
prev := len
}
return len
}

View file

@ -0,0 +1,21 @@
data := "
(
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
Sondag Maandag Dinsdag Woensdag Donderdag Vrydag Saterdag
E_djelë E_hënë E_martë E_mërkurë E_enjte E_premte E_shtunë
Ehud Segno Maksegno Erob Hamus Arbe Kedame
Al_Ahad Al_Ithinin Al_Tholatha'a Al_Arbia'a Al_Kamis Al_Gomia'a Al_Sabit
)"
for i, line in StrSplit(data, "`n", "`r")
{
line := RegExReplace(line, "\s+", " ")
len := AutoAbbreviations(line)
abbrev := ""
for j, day in StrSplit(line, " ")
abbrev .= SubStr(day, 1, len) " "
result .= len " > " abbrev "`n"
}
MsgBox % result
return

View file

@ -0,0 +1,19 @@
Loop, Read, days-of-the-week.txt ; input text in current dir
{
if (A_Index > 10) ; number of lines to output
break
Loop, Parse, A_LoopReadLine, %A_Space% ; create an array of the days
word%A_Index% := A_LoopField ; word1=sunday, word2=monday ...
loop
{
x := A_Index ;save the last loop index
abrev := ""
loop 7
abrev .= SubStr(word%A_Index%, 1, x) . "," ; x = length to test (1,2,3...)
sort, abrev, U D, ; sort unique (errorlevel = duplicates)
}
until ErrorLevel = 0 ;stay with last loop index (length)
minimalAb .= x . " " . A_LoopReadLine . " (" . abrev . ")`n"
}
msgbox % minimalAb
ExitApp

View file

@ -0,0 +1,66 @@
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> split(const std::string& str, char delimiter) {
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while (std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
int main() {
using namespace std;
string line;
int i = 0;
ifstream in("days_of_week.txt");
if (in.is_open()) {
while (getline(in, line)) {
i++;
if (line.empty()) {
continue;
}
auto days = split(line, ' ');
if (days.size() != 7) {
throw std::runtime_error("There aren't 7 days in line " + i);
}
map<string, int> temp;
for (auto& day : days) {
if (temp.find(day) != temp.end()) {
cerr << "" << line << '\n';
continue;
}
temp[day] = 1;
}
int len = 1;
while (true) {
temp.clear();
for (auto& day : days) {
string key = day.substr(0, len);
if (temp.find(key) != temp.end()) {
break;
}
temp[key] = 1;
}
if (temp.size() == 7) {
cout << setw(2) << len << " " << line << '\n';
break;
}
len++;
}
}
}
return 0;
}

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
namespace Abbreviations {
class Program {
static void Main(string[] args) {
string[] lines = System.IO.File.ReadAllLines("days_of_week.txt");
int i = 0;
foreach (string line in lines) {
i++;
if (line.Length > 0) {
var days = line.Split();
if (days.Length != 7) {
throw new Exception("There aren't 7 days in line " + i);
}
Dictionary<string, int> temp = new Dictionary<string, int>();
foreach (string day in days) {
if (temp.ContainsKey(day)) {
Console.WriteLine(" ∞ {0}", line);
continue;
}
temp.Add(day, 1);
}
int len = 1;
while (true) {
temp.Clear();
foreach(string day in days) {
string key;
if (len < day.Length) {
key = day.Substring(0, len);
} else {
key = day;
}
if (temp.ContainsKey(key)) {
break;
}
temp.Add(key, 1);
}
if (temp.Count == 7) {
Console.WriteLine("{0,2:D} {1}", len, line);
break;
}
len++;
}
}
}
}
}
}

View file

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void process(int lineNum, char buffer[]) {
char days[7][64];
int i = 0, d = 0, j = 0;
while (buffer[i] != 0) {
if (buffer[i] == ' ') {
days[d][j] = '\0';
++d;
j = 0;
} else if (buffer[i] == '\n' || buffer[i] == '\r') {
days[d][j] = '\0';
++d;
break;
} else {
days[d][j] = buffer[i];
++j;
}
if (d >= 7) {
printf("There aren't 7 days in line %d\n", lineNum);
return;
}
++i;
}
if (buffer[i] == '\0') {
days[d][j] = '\0';
++d;
}
if (d < 7) {
printf("There aren't 7 days in line %d\n", lineNum);
return;
} else {
int len = 0;
for (len = 1; len < 64; ++len) {
int d1;
for (d1 = 0; d1 < 7; ++d1) {
int d2;
for (d2 = d1 + 1; d2 < 7; ++d2) {
int unique = 0;
for (i = 0; i < len; ++i) {
if (days[d1][i] != days[d2][i]) {
unique = 1;
break;
}
}
if (!unique) {
goto next_length;
}
}
}
// uniqueness found for this length
printf("%2d ", len);
for (i = 0; i < 7; ++i) {
printf(" %s", days[i]);
}
printf("\n");
return;
// a duplication was found at the current length
next_length: {}
}
}
printf("Failed to find uniqueness within the bounds.");
}
int main() {
char buffer[1024];
int lineNum = 1, len;
FILE *fp;
fp = fopen("days_of_week.txt", "r");
while (1) {
memset(buffer, 0, sizeof(buffer));
fgets(buffer, sizeof(buffer), fp);
len = strlen(buffer);
if (len == 0 || buffer[len - 1] == '\0') {
break;
}
process(lineNum++, buffer);
}
fclose(fp);
return 0;
}

View file

@ -0,0 +1,158 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. AUTO-ABBREVIATIONS.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT DOW ASSIGN TO "days-of-week.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD DOW.
01 DOW-FILE PIC X(200).
WORKING-STORAGE SECTION. *> a.k.a. variables
01 DOW-LINE PIC X(200).
01 ENDO PIC 9(1).
01 ENDO2 PIC 9(1).
01 CURDAY PIC X(50).
01 ABPTR PIC 999.
01 LINE-NUM PIC 9(3) VALUE 1.
01 CHARAMT PIC 9(3) VALUE 1.
01 LARGESTCHARAMT PIC 9(3).
01 DAYNUM PIC 9(3) VALUE 1.
01 ABRESTART PIC 9(1).
01 CURABBR PIC X(50).
01 TMP1 PIC 9(3).
01 TMP2 PIC 9(3).
01 TINDEX PIC 9(3) VALUE 1.
01 ABBRLIST.
05 ABBRITEM PIC X(50) OCCURS 7 TIMES.
PROCEDURE DIVISION.
OPEN INPUT DOW.
PERFORM UNTIL ENDO = 1
READ DOW INTO DOW-LINE
AT END MOVE 1 TO ENDO
NOT AT END PERFORM
*> loop through each line
IF DOW-LINE = "" THEN
DISPLAY ""
ELSE
MOVE 0 TO ENDO2
MOVE 0 TO CHARAMT
PERFORM UNTIL ENDO2 > 0
MOVE 1 TO ABPTR
MOVE 1 TO DAYNUM
MOVE 0 TO ABRESTART
ADD 1 TO CHARAMT
*> reset the abbreviation table
MOVE 1 TO TINDEX
PERFORM 7 TIMES
MOVE SPACE TO ABBRITEM(TINDEX)
ADD 1 TO TINDEX
END-PERFORM
*> loop through each day
PERFORM 7 TIMES
UNSTRING DOW-LINE DELIMITED BY SPACE
INTO CURDAY
WITH POINTER ABPTR
END-UNSTRING
MOVE 0 TO TMP1
MOVE 0 TO TMP2
INSPECT CURDAY
TALLYING TMP1 FOR ALL CHARACTERS
INSPECT CURDAY
TALLYING TMP2 FOR ALL SPACE
SUBTRACT TMP2 FROM TMP1
IF TMP1 > LARGESTCHARAMT THEN
MOVE TMP1 TO LARGESTCHARAMT
END-IF
*> not enough days error
IF CURDAY = "" THEN
MOVE 3 TO ENDO2
END-IF
MOVE CURDAY(1:CHARAMT) TO CURABBR
*> check if the current abbreviation is already taken
MOVE 1 TO TINDEX
PERFORM 7 TIMES
IF ABBRITEM(TINDEX) = CURABBR THEN
MOVE 1 TO ABRESTART
END-IF
ADD 1 TO TINDEX
END-PERFORM
MOVE CURABBR TO ABBRITEM(DAYNUM)
ADD 1 TO DAYNUM
END-PERFORM
IF ABRESTART = 0 THEN
MOVE 1 TO ENDO2
END-IF
*> identical days error
IF CHARAMT > LARGESTCHARAMT THEN
MOVE 2 TO ENDO2
END-IF
END-PERFORM
DISPLAY "Line " LINE-NUM ": " WITH NO ADVANCING
IF ENDO2 = 3 THEN
DISPLAY "Error: not enough " WITH NO ADVANCING
DISPLAY "days"
ELSE IF ENDO2 = 2 THEN
DISPLAY "Error: identical " WITH NO ADVANCING
DISPLAY "days"
ELSE
DISPLAY CHARAMT ": " WITH NO ADVANCING
*> loop through each day and display its abbreviation
MOVE 1 TO TINDEX
PERFORM 7 TIMES
MOVE ABBRITEM(TINDEX) TO CURABBR
MOVE 0 TO TMP1
MOVE 0 TO TMP2
INSPECT CURABBR
TALLYING TMP1 FOR ALL CHARACTERS
INSPECT CURABBR
TALLYING TMP2 FOR TRAILING SPACES
SUBTRACT TMP2 FROM TMP1
DISPLAY CURABBR(1:TMP1) WITH NO ADVANCING
DISPLAY "." WITH NO ADVANCING
IF TINDEX < 7 THEN
DISPLAY SPACE WITH NO ADVANCING
ELSE
DISPLAY X"0a" WITH NO ADVANCING *> go to next line
END-IF
ADD 1 TO TINDEX
END-PERFORM
END-IF
END-IF
END-PERFORM
END-READ
ADD 1 TO LINE-NUM
END-PERFORM.
CLOSE DOW.
STOP RUN.

View file

@ -0,0 +1,9 @@
(defun max-mismatch (list)
(if (cdr list)
(max (apply #'max (mapcar #'(lambda (w2) (mismatch (car list) w2)) (cdr list))) (max-mismatch (cdr list)))
0 ))
(with-open-file (f "days-of-the-week.txt" :direction :input)
(do* ((row (read-line f nil nil) (read-line f nil nil)))
((null row) t)
(format t "~d ~a~%" (1+ (max-mismatch (SPLIT-SEQUENCE:split-sequence #\Space row))) row) ))

View file

@ -0,0 +1,36 @@
import std.conv;
import std.exception;
import std.range;
import std.stdio;
import std.string;
void main() {
foreach (size_t i, dstring line; File("days_of_week.txt").lines) {
line = chomp(line);
if (!line.empty) {
auto days = line.split;
enforce(days.length==7, text("There aren't 7 days in line ", i+1));
int[dstring] temp;
foreach(day; days) {
temp[day]++;
}
if (days.length < 7) {
writeln(" ∞ ", line);
continue;
}
int len = 1;
while (true) {
temp.clear();
foreach (day; days) {
temp[day.take(len).array]++;
}
if (temp.length == 7) {
writefln("%2d %s", len, line);
break;
}
len++;
}
}
}
}

View file

@ -0,0 +1,88 @@
program Abbreviations_Automatic;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.Generics.Collections,
System.IOUtils;
function DistinctStrings(strs: TArray<string>): TArray<string>;
begin
var l := length(strs);
var _set := TDictionary<string, Boolean>.Create;
SetLength(result, 0);
for var str in strs do
begin
if not _set.ContainsKey(str) then
begin
SetLength(result, Length(result) + 1);
result[High(result)] := str;
_set.AddOrSetValue(str, true);
end;
end;
_set.free;
end;
function takeRunes(s: string; n: Integer): string;
begin
var i := 0;
for var j := 0 to s.Length - 1 do
begin
if i = n then
exit(s.Substring(0, j));
inc(i);
end;
Result := s;
end;
begin
var lines := TFile.ReadAllLines('days_of_week.txt');
var lineCount := 0;
while lineCount < length(Lines) do
begin
var line := lines[lineCount].Trim;
inc(lineCount);
if line.IsEmpty then
begin
Writeln;
Continue;
end;
var days := line.Split([' '], TStringSplitOptions.ExcludeEmpty);
var daysLen := Length(days);
if daysLen <> 7 then
begin
Writeln('There aren''t 7 days in line', lineCount);
Readln;
halt;
end;
if Length(distinctStrings(days)) <> 7 then
begin
writeln(' infinity ', line);
Continue;
end;
var abbrevLen := 0;
while True do
begin
var abbrevs: TArray<string>;
SetLength(abbrevs, daysLen);
for var i := 0 to daysLen - 1 do
abbrevs[i] := takeRunes(days[i], abbrevLen);
if Length(distinctStrings(abbrevs)) = 7 then
begin
Writeln(abbrevLen.ToString.PadLeft(2).PadRight(3), line);
Break;
end;
inc(abbrevLen);
end;
end;
Readln;
end.

View file

@ -0,0 +1,36 @@
-module(abbreviateweekdays).
-export([ main/0 ]).
uniq(L,Acc) ->
io:fwrite("Min = ~p",[Acc]),
io:fwrite(" Abbr:~p~n",[ sets:to_list(L) ]).
uniq(_, L, Acc) ->
Abbr = [string:substr(X,1,Acc) || X <- L],
% list of abbrevs, starting with substring 1,1:
TempSet = sets:from_list( Abbr ),
TempSize = sets:size(TempSet),
if
TempSize =:= 7 ->
uniq(TempSet,Acc);
true -> uniq(0, L, Acc+1)
end.
read_lines(Device, Acc) when Acc < 19 ->
case file:read_line(Device) of
{ok, Line} ->
Tokenized = string:tokens(Line," "),
uniq(0,Tokenized,1),
read_lines(Device, Acc + 1);
eof ->
io:fwrite("~p~n",["Done"])
end;
read_lines(Device, 19) ->
io:fwrite("~p~n",["Done"]).
main() ->
{ok, Device} = (file:open("weekdays.txt", read)),
read_lines(Device, 1).

View file

@ -0,0 +1,2 @@
let fN g=let rec fN n=if g|>List.map(fun(g:string)->g.[0..n])|>Set.ofList|>Set.count=(List.length g) then (n+1) else fN(n+1)
fN 0

View file

@ -0,0 +1,5 @@
fN ["Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday"] // -> 2
fN ["Sondag"; "Maandag"; "Dinsdag"; "Woensdag"; "Donderdag"; "Vrydag"; "Saterdag"] // -> 2
fN ["E_djelë"; "E_hënë"; "E_martë"; "E_mërkurë"; "E_enjte"; "E_premte"; "E_shtunë"] // -> 4
fN ["Ehud"; "Segno"; "Maksegno"; "Erob"; "Hamus"; "Arbe"; "Kedame"] // -> 2
fN ["Al_Ahad"; "Al_Ithinin"; "Al_Tholatha'a"; "Al_Arbia'a"; "Al_Kamis"; "Al_Gomia'a"; "Al_Sabit";] // -> 5

View file

@ -0,0 +1,29 @@
USING: formatting io io.encodings.utf8 io.files kernel math
sequences sets splitting ;
IN: rosetta-code.abbreviations-automatic
: map-head ( seq n -- seq' ) [ short head ] curry map ;
: unique? ( seq n -- ? ) map-head all-unique? ;
: (abbr-length) ( seq -- n )
1 [ 2dup unique? ] [ 1 + ] until nip ;
: abbr-length ( str -- n/str )
[ "" ] [ " " split (abbr-length) ] if-empty ;
: show ( str -- ) dup abbr-length swap " %2u %s\n" printf ;
: labels ( -- )
"Min." "abbr" "Days of the week" "%s\n%s%32s\n" printf ;
: line ( n -- ) [ "=" write ] times ;
: header ( -- ) labels 4 line bl 75 line nl ;
: body ( -- ) [ show ] each-line ;
: abbreviations ( -- )
header "day-names.txt" utf8 [ body ] with-file-reader ;
MAIN: abbreviations

View file

@ -0,0 +1,60 @@
include "NSLog.incl"
include resources "DaysOfWeek.txt"
local fn DaysOfWeek as CFArrayRef
CFURLRef url
CFStringRef string
CFArrayRef weeks = NULL
url = fn BundleURLForResource( fn BundleMain, @"DaysOfWeek", @"txt", NULL )
string = fn StringWithContentsOfURL( url, NSUTF8StringEncoding, NULL )
if ( string )
weeks = fn StringComponentsSeparatedByCharactersInSet( string, fn CharacterSetNewlineSet )
end if
end fn = weeks
local fn MinAbbreviationLength( week as CFStringRef ) as long
CFArrayRef days
CFStringRef day1, day2, abbr
long count, length, minLen, index1, index2
minLen = 1
days = fn StringComponentsSeparatedByString( week, @" " )
if ( len( days ) == 7 )
count = len( days )
for index1 = 0 to count - 1
day1 = days[index1]
length = len( day1 )
abbr = left( day1, minLen )
for index2 = 0 to count - 1
if ( index2 == index1 ) then continue
day2 = days[index2]
while ( fn StringHasPrefix( day2, abbr ) )
minLen++
if ( minLen > length ) then break
abbr = left( day1, minLen )
wend
next
next
end if
end fn = minLen
void local fn Abbreviations
CFArrayRef weeks
CFStringRef week
weeks = fn DaysOfWeek
if ( weeks )
for week in weeks
if ( len(week) )
NSLog(@"%ld\t%@",fn MinAbbreviationLength( week ),week)
else
NSLog(@"NULL")
end if
next
end if
end fn
fn Abbreviations
HandleEvents

View file

@ -0,0 +1,75 @@
package main
import(
"bufio"
"fmt"
"os"
"strings"
)
func distinctStrings(strs []string) []string {
len := len(strs)
set := make(map[string]bool, len)
distinct := make([]string, 0, len)
for _, str := range strs {
if !set[str] {
distinct = append(distinct, str)
set[str] = true
}
}
return distinct
}
func takeRunes(s string, n int) string {
i := 0
for j := range s {
if i == n {
return s[:j]
}
i++
}
return s
}
func main() {
file, err := os.Open("days_of_week.txt")
if err != nil {
fmt.Println("Unable to open file.")
return
}
defer file.Close()
reader := bufio.NewReader(file)
lineCount := 0
for {
line, err := reader.ReadString('\n')
if err != nil { // end of file reached
return
}
line = strings.TrimSpace(line)
lineCount++
if line == "" {
fmt.Println()
continue
}
days := strings.Fields(line)
daysLen := len(days)
if (len(days) != 7) {
fmt.Println("There aren't 7 days in line", lineCount)
return
}
if len(distinctStrings(days)) != 7 { // implies some days have the same name
fmt.Println(" ∞ ", line)
continue
}
for abbrevLen := 1; ; abbrevLen++ {
abbrevs := make([]string, daysLen)
for i := 0; i < daysLen; i++ {
abbrevs[i] = takeRunes(days[i], abbrevLen)
}
if len(distinctStrings(abbrevs)) == 7 {
fmt.Printf("%2d %s\n", abbrevLen, line)
break
}
}
}
}

View file

@ -0,0 +1,45 @@
class Abbreviations {
static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("days_of_week.txt"), "utf-8"))
List<String> readAllLines = br.readLines()
for (int i = 0; i < readAllLines.size(); i++) {
String line = readAllLines.get(i)
if (line.length() == 0) continue
String[] days = line.split(" ")
if (days.length != 7) throw new RuntimeException("There aren't 7 days on line " + (i + 1))
Map<String, Integer> temp = new HashMap<>()
for (String day : days) {
Integer count = temp.getOrDefault(day, 0)
temp.put(day, count + 1)
}
if (temp.size() < 7) {
System.out.print(" ∞ ")
System.out.println(line)
continue
}
int len = 1
while (true) {
temp.clear()
for (String day : days) {
String sd
if (len >= day.length()) {
sd = day
} else {
sd = day.substring(0, len)
}
Integer count = temp.getOrDefault(sd, 0)
temp.put(sd, count + 1)
}
if (temp.size() == 7) {
System.out.printf("%2d %s\n", len, line)
break
}
len++
}
}
}
}

View file

@ -0,0 +1,28 @@
import Data.List (inits, intercalate, transpose)
import qualified Data.Set as S
--------------- MINIMUM ABBREVIATION LENGTH --------------
minAbbrevnLength :: [String] -> Int
minAbbrevlnLength [] = 0
minAbbrevnLength xs =
length . head . S.toList . head $
dropWhile ((< n) . S.size) $
S.fromList
<$> transpose (inits <$> xs)
where
n = length xs
--------------------------- TEST -------------------------
main :: IO ()
main = do
s <- readFile "./weekDayNames.txt"
mapM_ putStrLn $
take 10 $
intercalate "\t"
. (<*>)
[ show . minAbbrevnLength . words,
id
]
. return
<$> lines s

View file

@ -0,0 +1,19 @@
NB. y is words in boxes
abbreviation_length =: monad define
N =. # y
for_i. i. >: >./ #&> y do.
NB. if the length of the set of length i prefixes matches the length of the row
if. N -: # ~. i ({. &>) y do.
i return.
end.
end.
)
NB. use: auto_abbreviate DAY_NAMES
auto_abbreviate =: 3 :0
y =. y -. CR
lines =. [;._2 y
a =. <@([: <;._2 ,&' ');._2 y
L =. abbreviation_length&> a
((' ',~":)&> L) ,"1 lines
)

View file

@ -0,0 +1,52 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Abbreviations {
public static void main(String[] args) throws IOException {
Path path = Paths.get("days_of_week.txt");
List<String> readAllLines = Files.readAllLines(path);
for (int i = 0; i < readAllLines.size(); i++) {
String line = readAllLines.get(i);
if (line.length() == 0) continue;
String[] days = line.split(" ");
if (days.length != 7) throw new RuntimeException("There aren't 7 days on line " + (i + 1));
Map<String, Integer> temp = new HashMap<>();
for (String day : days) {
Integer count = temp.getOrDefault(day, 0);
temp.put(day, count + 1);
}
if (temp.size() < 7) {
System.out.print("");
System.out.println(line);
continue;
}
int len = 1;
while (true) {
temp.clear();
for (String day : days) {
String sd;
if (len >= day.length()) {
sd = day;
} else {
sd = day.substring(0, len);
}
Integer count = temp.getOrDefault(sd, 0);
temp.put(sd, count + 1);
}
if (temp.size() == 7) {
System.out.printf("%2d %s\n", len, line);
break;
}
len++;
}
}
}
}

View file

@ -0,0 +1,29 @@
Array.prototype.hasDoubles = function() {
let arr = this.slice();
while (arr.length > 1) {
let cur = arr.shift();
if (arr.includes(cur)) return true;
}
return false;
}
function getMinAbbrLen(arr) {
if (arr.length <= 1) return '';
let testArr = [],
len = 0, i;
do {
len++;
for (i = 0; i < arr.length; i++)
testArr[i] = arr[i].substr(0, len);
} while (testArr.hasDoubles());
return len;
}
// testing
for (let x = 0; x < list.length; x++) {
let days = list[x].split(' '),
l = getMinAbbrLen(days);
for (let y = 0; y < days.length; y++)
days[y] = days[y].substring(0, l);
document.write(`<p>(${l}): ${days.join('. ')}.</p>`);
}

View file

@ -0,0 +1,161 @@
(() => {
"use strict";
// ----- MINIMUM LENGTH OF UNIQUE ABBREVIATIONS ------
// minAbbrevnLength :: [String] -> Int
const minAbbrevnLength = xs => {
const n = xs.length;
return 0 < n ? (() => {
const
abbrs = dropWhile(ks => n > ks.length)(
transpose(xs.map(inits))
.map(prefixes => Array.from(
new Set(
prefixes.map(ws => ws.join(""))
)
))
);
return (abbrs.length && abbrs[0][0].length) || (
maximum(xs.map(x => x.length))
);
})() : 0;
};
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
readFile(
"~/Desktop/weekDayNames.txt"
)
.split("\n")
// Display of just the first few lines.
.slice(0, 10)
.map(s => {
const
ws = words(s),
n = minAbbrevnLength(ws);
return `${n}: ${ws.map(w => w.slice(0, n))}`;
})
.join("\n");
// ----------- MACOS JS FOR AUTOMATION IO ------------
// readFile :: FilePath -> IO String
const readFile = fp => {
// The contents of a text file at the
// filepath fp.
const
e = $(),
ns = $.NSString
.stringWithContentsOfFileEncodingError(
$(fp).stringByStandardizingPath,
$.NSUTF8StringEncoding,
e
);
return ObjC.unwrap(
ns.isNil() ? (
e.localizedDescription
) : ns
);
};
// --------------------- GENERIC ---------------------
// dropWhile :: (a -> Bool) -> [a] -> [a]
// dropWhile :: (Char -> Bool) -> String -> String
const dropWhile = p =>
// The suffix remainining after takeWhile p xs.
xs => {
const n = xs.length;
return xs.slice(
0 < n ? until(
i => n === i || !p(xs[i])
)(i => 1 + i)(0) : 0
);
};
// inits :: [a] -> [[a]]
// inits :: String -> [String]
const inits = xs =>
// All prefixes of the argument,
// shortest first.
[...xs].map(
(_, i, ys) => ys.slice(0, 1 + i)
);
// maximum :: Ord a => [a] -> a
const maximum = xs => (
// The largest value in a non-empty list.
ys => 0 < ys.length ? (
ys.slice(1).reduce(
(a, y) => y > a ? (
y
) : a, ys[0]
)
) : undefined
)(xs);
// transpose :: [[a]] -> [[a]]
const transpose = rows => {
// If any rows are shorter than those that follow,
// their elements are skipped:
// > transpose [[10,11],[20],[],[30,31,32]]
// == [[10,20,30],[11,31],[32]]
const go = xss =>
0 < xss.length ? (() => {
const
h = xss[0],
t = xss.slice(1);
return 0 < h.length ? [
[h[0]].concat(t.reduce(
(a, xs) => a.concat(
0 < xs.length ? (
[xs[0]]
) : []
),
[]
))
].concat(go([h.slice(1)].concat(
t.map(xs => xs.slice(1))
))) : go(t);
})() : [];
return go(rows);
};
// until :: (a -> Bool) -> (a -> a) -> a -> a
const until = p =>
// The value resulting from repeated applications
// of f to the seed value x, terminating when
// that result returns true for the predicate p.
f => x => {
let v = x;
while (!p(v)) {
v = f(v);
}
return v;
};
// words :: String -> [String]
const words = s =>
// List of space-delimited sub-strings.
s.split(/\s+/u);
// MAIN ---
return main();
})();

View file

@ -0,0 +1,24 @@
def trim: sub("^ *";"") | sub(" $";"");
# Each item in the stream should be a string with $n names
def minimum_abbreviation_lengths(stream; $n):
foreach (stream|trim) as $line ({i: 0};
.i+=1
| if $line == "" then .emit = ""
else [$line|splits(" *")] as $days
| if ($days|length != $n) then .emit = "WARNING: line \(.i) does not have \($n) tokens"
elif ($days|unique|length < $n) # some days have the same name
then .emit = "∞: \($line)"
else .len = 1
| .emit = false
| until(.emit;
.len as $len
| if ($days|map(.[:$len])|unique|length == $n)
then .emit = "\($len): \($line)"
else .len += 1
end)
end
end;
.emit) ;
minimum_abbreviation_lengths(inputs; 7)

View file

@ -0,0 +1,126 @@
const text = """
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
Sondag Maandag Dinsdag Woensdag Donderdag Vrydag Saterdag
E_djelë E_hënë E_martë E_mërkurë E_enjte E_premte E_shtunë
Ehud Segno Maksegno Erob Hamus Arbe Kedame
Al_Ahad Al_Ithinin Al_Tholatha'a Al_Arbia'a Al_Kamis Al_Gomia'a Al_Sabit
Guiragui Yergou_shapti Yerek_shapti Tchorek_shapti Hink_shapti Ourpat Shapat
domingu llunes martes miércoles xueves vienres sábadu
Bazar_gÜnÜ Birinci_gÜn Çkinci_gÜn ÜçÜncÜ_gÜn DÖrdÜncÜ_gÜn Bes,inci_gÜn Altòncò_gÜn
Igande Astelehen Astearte Asteazken Ostegun Ostiral Larunbat
Robi_bar Shom_bar Mongal_bar Budhh_bar BRihashpati_bar Shukro_bar Shoni_bar
Nedjelja Ponedeljak Utorak Srijeda Cxetvrtak Petak Subota
Disul Dilun Dimeurzh Dimerc'her Diriaou Digwener Disadorn
nedelia ponedelnik vtornik sriada chetvartak petak sabota
sing_kei_yaht sing_kei_yat sing_kei_yee sing_kei_saam sing_kei_sie sing_kei_ng sing_kei_luk
Diumenge Dilluns Dimarts Dimecres Dijous Divendres Dissabte
Dzeenkk-eh Dzeehn_kk-ehreh Dzeehn_kk-ehreh_nah_kay_dzeeneh Tah_neesee_dzeehn_neh Deehn_ghee_dzee-neh Tl-oowey_tts-el_dehlee Dzeentt-ahzee
dy_Sul dy_Lun dy_Meurth dy_Mergher dy_You dy_Gwener dy_Sadorn
Dimanch Lendi Madi Mèkredi Jedi Vandredi Samdi
nedjelja ponedjeljak utorak srijeda cxetvrtak petak subota
nede^le ponde^lí úterÿ str^eda c^tvrtek pátek sobota
Sondee Mondee Tiisiday Walansedee TOOsedee Feraadee Satadee
s0ndag mandag tirsdag onsdag torsdag fredag l0rdag
zondag maandag dinsdag woensdag donderdag vrijdag zaterdag
Diman^co Lundo Mardo Merkredo ^Jaùdo Vendredo Sabato
pÜhapäev esmaspäev teisipäev kolmapäev neljapäev reede laupäev
Diu_prima Diu_sequima Diu_tritima Diu_quartima Diu_quintima Diu_sextima Diu_sabbata
sunnudagur mánadagur tÿsdaguy mikudagur hósdagur friggjadagur leygardagur
Yek_Sham'beh Do_Sham'beh Seh_Sham'beh Cha'har_Sham'beh Panj_Sham'beh Jom'eh Sham'beh
sunnuntai maanantai tiistai keskiviiko torsktai perjantai lauantai
dimanche lundi mardi mercredi jeudi vendredi samedi
Snein Moandei Tiisdei Woansdei Tonersdei Freed Sneon
Domingo Segunda_feira Martes Mércores Joves Venres Sábado
k'vira orshabati samshabati otkhshabati khutshabati p'arask'evi shabati
Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag
Kiriaki' Defte'ra Tri'ti Teta'rti Pe'mpti Paraskebi' Sa'bato
ravivaar somvaar mangalvaar budhvaar guruvaar shukravaar shanivaar
pópule pó`akahi pó`alua pó`akolu pó`ahá pó`alima pó`aono
Yom_rishon Yom_sheni Yom_shlishi Yom_revi'i Yom_chamishi Yom_shishi Shabat
ravivara somavar mangalavar budhavara brahaspativar shukravara shanivar
vasárnap hétfö kedd szerda csütörtök péntek szombat
Sunnudagur Mánudagur ╞riδjudagur Miδvikudagar Fimmtudagur FÖstudagur Laugardagur
sundio lundio mardio merkurdio jovdio venerdio saturdio
Minggu Senin Selasa Rabu Kamis Jumat Sabtu
Dominica Lunedi Martedi Mercuridi Jovedi Venerdi Sabbato
Dé_Domhnaigh Dé_Luain Dé_Máirt Dé_Ceadaoin Dé_ardaoin Dé_hAoine Dé_Sathairn
domenica lunedí martedí mercoledí giovedí venerdí sabato
Nichiyou_bi Getzuyou_bi Kayou_bi Suiyou_bi Mokuyou_bi Kin'you_bi Doyou_bi
Il-yo-il Wol-yo-il Hwa-yo-il Su-yo-il Mok-yo-il Kum-yo-il To-yo-il
Dies_Dominica Dies_Lunæ Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Saturni
sve-tdien pirmdien otrdien tresvdien ceturtdien piektdien sestdien
Sekmadienis Pirmadienis Antradienis Trec^iadienis Ketvirtadienis Penktadienis S^es^tadienis
Wangu Kazooba Walumbe Mukasa Kiwanuka Nnagawonye Wamunyi
xing-_qi-_rì xing-_qi-_yi-. xing-_qi-_èr xing-_qi-_san-. xing-_qi-_sì xing-_qi-_wuv. xing-_qi-_liù
Jedoonee Jelune Jemayrt Jecrean Jardaim Jeheiney Jesam
Jabot Manre Juje Wonje Taije Balaire Jarere
geminrongo minòmishi mártes mièrkoles misheushi bèrnashi mishábaro
Ahad Isnin Selasa Rabu Khamis Jumaat Sabtu
sφndag mandag tirsdag onsdag torsdag fredag lφrdag
lo_dimenge lo_diluns lo_dimarç lo_dimèrcres lo_dijòus lo_divendres lo_dissabte
djadomingo djaluna djamars djarason djaweps djabièrna djasabra
Niedziela Poniedzial/ek Wtorek S,roda Czwartek Pia,tek Sobota
Domingo segunda-feire terça-feire quarta-feire quinta-feire sexta-feira såbado
Domingo Lunes martes Miercoles Jueves Viernes Sabado
Duminicª Luni Mart'i Miercuri Joi Vineri Sâmbªtª
voskresenie ponedelnik vtornik sreda chetverg pyatnitsa subbota
Sunday Di-luain Di-màirt Di-ciadain Di-ardaoin Di-haoine Di-sathurne
nedjelja ponedjeljak utorak sreda cxetvrtak petak subota
Sontaha Mmantaha Labobedi Laboraro Labone Labohlano Moqebelo
Iridha- Sandhudha- Anga.haruwa-dha- Badha-dha- Brahaspa.thindha- Sikura-dha- Sena.sura-dha-
nedel^a pondelok utorok streda s^tvrtok piatok sobota
Nedelja Ponedeljek Torek Sreda Cxetrtek Petek Sobota
domingo lunes martes miércoles jueves viernes sábado
sonde mundey tude-wroko dride-wroko fode-wroko freyda Saturday
Jumapili Jumatatu Jumanne Jumatano Alhamisi Ijumaa Jumamosi
söndag måndag tisdag onsdag torsdag fredag lordag
Linggo Lunes Martes Miyerkoles Huwebes Biyernes Sabado
Lé-pài-jít Pài-it Pài-jï Pài-sañ Pài-sì Pài-gÖ. Pài-lák
wan-ar-tit wan-tjan wan-ang-kaan wan-phoet wan-pha-ru-hat-sa-boh-die wan-sook wan-sao
Tshipi Mosupologo Labobedi Laboraro Labone Labotlhano Matlhatso
Pazar Pazartesi Sali Çar,samba Per,sembe Cuma Cumartesi
nedilya ponedilok vivtorok sereda chetver pyatnytsya subota
Chu?_Nhâ.t Thú*_Hai Thú*_Ba Thú*_Tu* Thú*_Na'm Thú*_Sáu Thú*_Ba?y
dydd_Sul dyds_Llun dydd_Mawrth dyds_Mercher dydd_Iau dydd_Gwener dyds_Sadwrn
Dibeer Altine Talaata Allarba Al_xebes Aljuma Gaaw
iCawa uMvulo uLwesibini uLwesithathu uLuwesine uLwesihlanu uMgqibelo
zuntik montik dinstik mitvokh donershtik fraytik shabes
iSonto uMsombuluko uLwesibili uLwesithathu uLwesine uLwesihlanu uMgqibelo
Dies_Dominica Dies_Lunæ Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Saturni
Bazar_gÜnÜ Bazar_ærtæsi Çærs,ænbæ_axs,amò Çærs,ænbæ_gÜnÜ CÜmæ_axs,amò CÜmæ_gÜnÜ CÜmæ_Senbæ
Sun Moon Mars Mercury Jove Venus Saturn
zondag maandag dinsdag woensdag donderdag vrijdag zaterdag
KoseEraa GyoOraa BenEraa Kuoraa YOwaaraa FeEraa Memenaa
Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Sonnabend
Domingo Luns Terza_feira Corta_feira Xoves Venres Sábado
Dies_Solis Dies_Lunae Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Sabbatum
xing-_qi-_tiàn xing-_qi-_yi-. xing-_qi-_èr xing-_qi-_san-. xing-_qi-_sì xing-_qi-_wuv. xing-_qi-_liù
djadomingu djaluna djamars djarason djaweps djabièrnè djasabra
Killachau Atichau Quoyllurchau Illapachau Chaskachau Kuychichau Intichau"""
function processweek(txt)
for lin in split(txt, "\n")
print(lin)
if length(lin) < 7
println("A blank line returns \"\", a blank string.")
continue
end
words = map(x->"$x", split(lin, r"\s+"))
minlen = minimum(map(length, words))
abbrev = fill("", length(words))
for i in 1:minlen
if length(unique(wrd -> split(wrd, "")[1:i], words)) == length(words)
for (k, word) in enumerate(words)
abbrev[k] = join(split(word, "")[1:i], "")
end
println(" => ", abbrev, ", which are length ", i)
break
elseif i == minlen
println(" => Could not find abbreviations for the week")
end
end
end
end
processweek(text)

View file

@ -0,0 +1,29 @@
// version 1.1.4-3
import java.io.File
val r = Regex("[ ]+")
fun main(args: Array<String>) {
val lines = File("days_of_week.txt").readLines()
for ((i, line) in lines.withIndex()) {
if (line.trim().isEmpty()) {
println()
continue
}
val days = line.trim().split(r)
if (days.size != 7) throw RuntimeException("There aren't 7 days in line ${i + 1}")
if (days.distinct().size < 7) { // implies some days have the same name
println(" ∞ $line")
continue
}
var len = 1
while (true) {
if (days.map { it.take(len) }.distinct().size == 7) {
println("${"%2d".format(len)} $line")
break
}
len++
}
}
}

View file

@ -0,0 +1,34 @@
import java.io.File
import kotlin.math.max
fun getMinimumPrefixLength(distinctWords: Iterable<String>): Int {
return distinctWords
.sorted()
.fold(Pair("", 0),
{ (previousWord, minLength), currentWord ->
val firstNonMatchingIdx = previousWord
.asSequence()
.zip(currentWord.asSequence())
.indexOfFirst { it.first != it.second }
return@fold Pair(
currentWord,
max(
// firstNonMatchingIdx would be -1 iff previousWord is a prefix of currentWord
if (firstNonMatchingIdx != -1) firstNonMatchingIdx + 1 else previousWord.length + 1,
minLength)
)
})
.second
}
fun getMinimumPrefixLength(whitespaceSeparatedDistinctWords: String) =
getMinimumPrefixLength(whitespaceSeparatedDistinctWords.split(Regex("\\s+")))
fun main() {
File("/tmp/input.txt").useLines {
it.map(String::trim)
.filter(String::isNotEmpty)
.map({ "${getMinimumPrefixLength(it).toString().padEnd(5)} ${it}" })
.forEach(::println)
}
}

View file

@ -0,0 +1,80 @@
#!/bin/ksh
# Abbreviations, automatic
# # Variables:
#
dow_file='../dow'
typeset -T Dow_T=(
typeset -a -h "Week day name array" dow
typeset -si -h "minimum length abbreviation" minabv
function init_dow {
_.minabv=$1
_.dow=( $2 )
}
function print_wk {
typeset i ; typeset -si i
printf "(%d) " ${_.minabv}
for((i=0; i<${#_.dow[*]}; i++)); do
printf "%${_.minabv}s " ${_.dow[i]:0:${_.minabv}}
done
printf "\n"
}
)
# # Functions:
#
# # Function _file2arr(fn, arr) - read file fn into arr
#
function _file2arr {
typeset _fn ; _fn="$1"
typeset _arr ; nameref _arr="$2"
typeset _i ; typeset -si _i=0
while read; do
_arr[_i++]="$REPLY"
done < ${_fn}
}
# # Function _minabbr(buff) - return the min length abbr for items in buff
#
function _minabbr {
typeset _buf ; _buf="$1"
typeset _i _flg ; typeset -si _i=0 _cnt
typeset _item _list _abr
until (( _cnt == 7 )); do
unset _list
_cnt=0
(( _i++ ))
for _item in ${_buf}; do
_abr=${_item:0:${_i}}
[[ ${_abr} == @(${_list}) ]] && break
_list+="${_abr}|"
(( _cnt++ ))
done
done
echo ${_i}
}
######
# main #
######
typeset -a dow langs
_file2arr "${dow_file}" dow
for ((i=0; i<${#dow[*]}; i++)); do
(( ! ${#dow[i]} )) && { print "Blank Input, line $((i+1))" ; continue ;}
alen=$(_minabbr "${dow[i]}")
Dow_T langs[i]
langs[i].init_dow ${alen} "${dow[i]}"
(( $((RANDOM%100+1))<=5 )) && { printf "%d. " $((i+1)) ; langs[i].print_wk ;}
done

View file

@ -0,0 +1,51 @@
function split(line)
local wa = {}
for i in string.gmatch(line, "%S+") do
table.insert(wa, i)
end
return wa
end
-- main
local file = assert(io.open("days_of_week.txt", "r"))
io.input(file)
local line_num = 0
while true do
local line = io.read()
if line == nil then break end
line_num = line_num + 1
if string.len(line) > 0 then
local days = split(line)
if #days ~= 7 then
error("There aren't 7 days in line "..line_num)
end
local temp = {}
for i,day in pairs(days) do
if temp[day] ~= nil then
io.stderr:write(""..line.."\n")
else
temp[day] = true
end
end
local length = 1
while length < 50 do
temp = {}
local count = 0
for i,day in pairs(days) do
local key = string.sub(day, 0, length)
if temp[key] ~= nil then break end
temp[key] = true
count = count + 1
end
if count == 7 then
print(string.format("%2d %s", length, line))
break
end
length = length + 1
end
end
end

View file

@ -0,0 +1,13 @@
(*This function gives all 'heads' of str of length 1 to maxLength. Since the input data was formatted to use underscores in place of spaces, there is an edge case where distinct abbreviations derived from the input data would actually not be distinct in the 'real' abbreviations. See further comments below regarding the difference between my output and the output of other solutions.*)
Abbreviations[maxLength_Integer][str_String]:=Array[StringTake[StringPadRight[str,maxLength,"_"],#]&,maxLength];
(*Given a list of words (weekday names), this function expands each to its abbreviations and then picks the first 'column' that contains no duplicates. The failure case isn't really needed for this specific data, but I included it for completeness.*)
ShortestUniqueAbbreviations[list:{__String}]:=
With[
{maxLength=Max[StringLength/@list]},
SelectFirst[Transpose[Abbreviations[maxLength]/@list],DuplicateFreeQ,"no unique abbreviations possible"]
];
(*This function gives the minimum number of characters to distinguish the words (weekday names). It assumes data is a space separated list of weekday names (i.e. one line of the input data). I would prefer to ignore blank lines, but the spec says to return an empty string. Since all of the abbreviations should be the same length because of the padding done by Abbreviations, I could have just selected the first item rather than taking the Max of the StringLength. However, the implmenetation of Abbreviations was very specific to the format of the input data, and so using Max seemed a bit safer and more general.*)
RequiredAbbreviationLength[""]="";
RequiredAbbreviationLength[input_String]:=Max[StringLength/@ShortestUniqueAbbreviations[StringSplit[input]]];

View file

@ -0,0 +1,31 @@
import sets
import unicode
type Runes = seq[Rune]
var linenum = 0
for line in lines("days.txt"):
inc linenum
if line.len > 0:
# Extract the day names and store them in a sorted list of sequences of runes.
var days: seq[Runes]
for day in line.splitWhitespace():
days.add(day.toLower.toRunes)
if days.len != 7:
echo "Wrong number of days at line ", linenum
# Build the abbreviations and store them in a set.
var index = 0
while true:
var abbrevs: HashSet[seq[Rune]]
for day in days:
abbrevs.incl(day[0..min(index, day.high)])
if abbrevs.card == 7:
# All abbreviations are different: fine!
break
inc index
echo index + 1, " ", line
else:
echo line

View file

@ -0,0 +1,31 @@
import algorithm
import unicode
type Runes = seq[Rune]
var linenum = 0
for line in lines("days.txt"):
inc linenum
if line.len > 0:
# Extract the day names and store them in a sorted list of sequences of runes.
var days: seq[Runes]
for day in sorted(line.toLower.splitWhitespace()):
days.add(day.toRunes)
if days.len != 7:
echo "Wrong number of days at line ", linenum
# Compare the first letters of successive day names, incrementing the upper index if necessary.
var index = 0 # Equal to abbreviation length - 1.
var prevday = days[0]
for idx in 1..days.high:
let currday = days[idx]
if currday == prevday:
echo "Double encountered at line ", linenum
while currday[0..min(index, currday.high)] == prevday[0..min(index, prevday.high)]:
inc index
prevday = currday
echo index + 1, " ", line
else:
echo line

View file

@ -0,0 +1,66 @@
use System.IO.File;
use Collection;
class Abbreviations {
function : Main(args : String[]) ~ Nil {
if(args->Size() = 1) {
Go(args[0]);
};
}
function : Go(file : String) ~ Nil {
reader := FileReader->New(file);
leaving {
reader->Close();
};
cache := StringMap->New();
line := reader->ReadString();
while(line <> Nil) {
if(line->Size() > 0) {
days := line->Split(" ");
cache->Empty();
each(i : days) {
day := days[i];
cache->Insert(day, IntHolder->New(1));
};
if(cache->Size() < 7) {
" ∞ {$line}"->PrintLine();
};
len := 1;
while(true) {
cache->Empty();
each(i : days) {
day := days[i];
sd : String;
if(len >= day->Size()) {
sd := day;
}
else {
sd := day->SubString(len);
};
count := cache->Find(sd)->As(IntHolder);
if(count = Nil) {
cache->Insert(sd, IntHolder->New(1));
}
else {
count->Inc();
};
};
if(cache->Size() = 7) {
"{$len} {$line}"->PrintLine();
break;
};
len += 1;
};
};
line := reader->ReadString();
};
}
}

View file

@ -0,0 +1,21 @@
use strict;
use utf8;
binmode STDOUT, ":utf8";
sub auto_abbreviate {
my($string) = @_;
my @words = split ' ', $string;
my $max = 0;
return '' unless @words;
map { $max = length($_) if length($_) > $max } @words;
for $i (1..$max) {
my %seen;
return $i if @words == grep {!$seen{substr($_,0,$i)}++} @words;
}
return '∞';
}
open $fh, '<:encoding(UTF-8)', 'DoWAKA.txt';
while ($_ = <$fh>) {
print "$.) " . auto_abbreviate($_) . ' ' . $_;
}

View file

@ -0,0 +1,21 @@
-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"abbrev_auto.txt"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">GT_LF_STRIPPED</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">days</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">,</span><span style="color: #000000;">no_empty</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">7</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">7</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">7</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]))</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">days</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">m</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">days</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">m</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</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;">for</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: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">len</span><span style="color: #0000FF;">,</span><span style="color: #000000;">li</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>
<!--

View file

@ -0,0 +1,33 @@
import util.
max_length(Words) = Max =>
Lengths = [len(W): W in Words],
Max = max(Lengths).
min_abbr([]) = 0.
min_abbr(Line) = Min =>
Words = split(Line),
Max = max_length(Words),
I = 0,
Abbrevs = [],
Uniqs = [],
do
I := I + 1,
Abbrevs := [slice(W, 1, I): W in Words],
Uniqs := sort_remove_dups(Abbrevs)
while (I < Max, len(Abbrevs) > len(Uniqs)),
Min = I.
main(Args) =>
File = Args[1],
Reader = open(File),
while (not at_end_of_stream(Reader))
Line := read_line(Reader),
Min := min_abbr(Line),
if (Min > 0) then
printf("%d %s\n", Min, Line)
else
nl
end
end.

View file

@ -0,0 +1,53 @@
minimum_abbreviation_length(Day_names, Min_length):-
sort(Day_names, Sorted_names),
minimum_abbreviation_length(Sorted_names, Min_length, 1).
minimum_abbreviation_length([_], Min_length, Min_length):- !.
minimum_abbreviation_length([Name1, Name2|Rest], Min_length, M1):-
common_prefix_length(Name1, Name2, Length),
M2 is max(M1, Length + 1),
minimum_abbreviation_length([Name2|Rest], Min_length, M2).
common_prefix_length(String1, String2, Length):-
string_chars(String1, Chars1),
string_chars(String2, Chars2),
common_prefix_length1(Chars1, Chars2, Length, 0).
common_prefix_length1([], _, Length, Length):-!.
common_prefix_length1(_, [], Length, Length):-!.
common_prefix_length1([C1|_], [C2|_], Length, Length):-
C1 \= C2,
!.
common_prefix_length1([C|Chars1], [C|Chars2], Length, L1):-
L2 is L1 + 1,
common_prefix_length1(Chars1, Chars2, Length, L2).
to_upper_case([], []):-!.
to_upper_case([String|S], [Upper_case|U]):-
string_upper(String, Upper_case),
to_upper_case(S, U).
process_line(""):-
nl,
!.
process_line(Line):-
split_string(Line, "\s\t", "\s\t", Day_names),
to_upper_case(Day_names, Upper),
minimum_abbreviation_length(Upper, Length),
writef('%w %w\n', [Length, Line]).
process_stream(Stream):-
read_line_to_string(Stream, String),
String \= end_of_file,
!,
process_line(String),
process_stream(Stream).
process_stream(_).
process_file(File):-
open(File, read, Stream),
process_stream(Stream),
close(Stream).
main:-
process_file("days_of_week.txt").

View file

@ -0,0 +1,46 @@
EnableExplicit
#TZ="|"
#FZ="@"
#WORD_SEPARATOR=Chr(32)
Declare.i abbreviations(txt.s)
Define dataset.s, line_number.i, line_cache.s, result.i, word_index.i, word.s
If OpenConsole("abbreviations-automatic") And ReadFile(0,"./Data/days_of_the_week.txt")
dataset=ReadString(0,#PB_UTF8|#PB_File_IgnoreEOL) : CloseFile(0)
line_number=1
Repeat
line_cache=StringField(dataset,line_number,#LF$)
If Len(line_cache)=0
PrintN("")
Else
result=abbreviations(line_cache) : PrintN(RSet(Str(result),3)+": "+line_cache)
word_index=1
word=StringField(line_cache,word_index,#WORD_SEPARATOR)
If word : Print(Space(5)) : EndIf
While word
Print(LSet(Left(word,result),Len(word)+1))
word_index+1 : word=StringField(line_cache,word_index,#WORD_SEPARATOR)
Wend
PrintN("")
EndIf
line_number+1
Until line_number>CountString(dataset,#LF$)
Input()
EndIf
Procedure.b CompareLetters(sfield.s,letters.i,separator.s=#WORD_SEPARATOR)
Define word_index.i, buf.s
For word_index=1 To CountString(sfield,separator)+1
buf+LSet(Left(StringField(sfield,word_index,separator),letters),letters,#FZ)+#TZ
Next
For word_index=1 To CountString(buf,#TZ)
If CountString(buf,StringField(buf,word_index,#TZ))>1 : ProcedureReturn #True : EndIf
Next
ProcedureReturn #False
EndProcedure
Procedure.i abbreviations(txt.s)
Define letters.i=1
While CompareLetters(txt,letters) : letters+1 : Wend
ProcedureReturn letters
EndProcedure

View file

@ -0,0 +1,28 @@
def shortest_abbreviation_length(line, list_size):
words = line.split()
word_count = len(words)
# Can't give true answer with unexpected number of entries
if word_count != list_size:
raise ValueError(f'Not enough entries, expected {list_size} found {word_count}')
# Find the small slice length that gives list_size unique values
abbreviation_length = 1
abbreviations = set()
while(True):
abbreviations = {word[:abbreviation_length] for word in words}
if len(abbreviations) == list_size:
return abbreviation_length
abbreviation_length += 1
abbreviations.clear()
def automatic_abbreviations(filename, words_per_line):
with open(filename) as file:
for line in file:
line = line.rstrip()
if len(line) > 0:
length = shortest_abbreviation_length(line, words_per_line)
print(f'{length:2} {line}')
else:
print()
automatic_abbreviations('daysOfWeek.txt', 7)

View file

@ -0,0 +1,54 @@
import operator
from itertools import (accumulate,
repeat)
from pathlib import Path
from typing import (Iterator,
List,
Tuple)
FILEPATH = Path('days_of_week.txt')
def read_lines(path: Path) -> Iterator[str]:
with path.open() as file:
yield from file
def cumulative_letters(word: str) -> Iterator[str]:
"""For a word 'foo' yields 'f', 'fo', 'foo', 'foo', 'foo', ..."""
yield from accumulate(word, operator.add)
yield from repeat(word)
def words_cumulative_letters(words: List[str]) -> Iterator[Tuple[str, ...]]:
"""Yields cumulative letters for several words at the same time"""
yield from zip(*map(cumulative_letters, words))
def longest_string_length(strings: Tuple[str, ...]) -> int:
return max(map(len, strings))
def min_abbreviation_length(words: List[str]) -> int:
def are_unique(abbreviations: Tuple[str, ...]) -> bool:
return len(set(abbreviations)) == len(words)
unique_abbreviations = filter(are_unique, words_cumulative_letters(words))
return longest_string_length(next(unique_abbreviations))
def main():
for line in read_lines(FILEPATH):
words = line.split()
if not words:
print()
continue
count = min_abbreviation_length(words)
print(f'{count} {line}', end='')
if __name__ == '__main__':
main()

View file

@ -0,0 +1,124 @@
'''Automatic abbreviations'''
from itertools import (accumulate, chain)
from os.path import expanduser
# abbrevLen :: [String] -> Int
def abbrevLen(xs):
'''The minimum length of prefix required to obtain
a unique abbreviation for each string in xs.'''
n = len(xs)
return next(
len(a[0]) for a in map(
compose(nub)(map_(concat)),
transpose(list(map(inits, xs)))
) if n == len(a)
)
# TEST ----------------------------------------------------
def main():
'''Test'''
xs = map_(strip)(
lines(readFile('weekDayNames.txt'))
)
for i, n in enumerate(map(compose(abbrevLen)(words), xs)):
print(n, ' ', xs[i])
# GENERIC -------------------------------------------------
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Function composition.'''
return lambda f: lambda x: g(f(x))
# concat :: [String] -> String
def concat(xs):
'''The concatenation of a list of strings.'''
return ''.join(xs)
# inits :: [a] -> [[a]]
def inits(xs):
'''all initial segments of xs, shortest first.'''
return list(scanl(lambda a, x: a + [x])(
[]
)(list(xs)))
# lines :: String -> [String]
def lines(s):
'''A list of strings,
(containing no newline characters)
derived from a single new-line delimited string.'''
return s.splitlines()
# map :: (a -> b) -> [a] -> [b]
def map_(f):
'''The list obtained by applying f
to each element of xs.'''
return lambda xs: list(map(f, xs))
# nub :: [a] -> [a]
def nub(xs):
'''A list containing the same elements as xs,
without duplicates, in the order of their
first occurrence.'''
return list(dict.fromkeys(xs))
# readFile :: FilePath -> IO String
def readFile(fp):
'''The contents of any file at the path
derived by expanding any ~ in fp.'''
with open(expanduser(fp), 'r', encoding='utf-8') as f:
return f.read()
# scanl :: (b -> a -> b) -> b -> [a] -> [b]
def scanl(f):
'''scanl is like reduce, but returns a succession of
intermediate values, building from the left.'''
return lambda a: lambda xs: (
accumulate(chain([a], xs), f)
)
# strip :: String -> String
def strip(s):
'''A copy of s without any leading or trailling
white space.'''
return s.strip()
# transpose :: Matrix a -> Matrix a
def transpose(m):
'''The rows and columns of the argument transposed.
(The matrix containers and rows can be lists or tuples).'''
if m:
inner = type(m[0])
z = zip(*m)
return (type(m))(
map(inner, z) if tuple != inner else z
)
else:
return m
# words :: String -> [String]
def words(s):
'''A list of words delimited by characters
representing white space.'''
return s.split()
# MAIN ---
if __name__ == '__main__':
main()

View file

@ -0,0 +1,29 @@
/*REXX program finds the minimum length abbreviation for a lists of words (from a file).*/
parse arg uw /*obtain optional arguments from the CL*/
iFID= 'ABBREV_A.TAB' /*name of the file that has the table. */
say 'minimum' /*display the first part of the title. */
say 'abbrev' center("days of the week", 80) /*display the title for the output. */
say '' center("", 80, '') /*display separator for the title line.*/
/* [↓] process the file until done. */
do while lines(iFID)\==0; days=linein(iFID) /*read a line (should contain 7 words).*/
minLen= abb(days) /*find the minimum abbreviation length.*/
say right(minLen, 4) ' ' days /*display a somewhat formatted output. */
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
abb: procedure; parse arg x; #=words(x) /*obtain list of words; find how many.*/
if #==0 then return '' /*check for a blank line or null line. */
@.= /*@. is a stemmed array of the words.*/
L=0 /*L is the max length of " " */
do j=1 for #; @.j=word(x, j) /*assign to array for faster processing*/
L.j=length(@.j); L= max(L, L.j) /*find the maximum length of any item. */
end /*L*/
/* [↓] determine minimum abbrev length*/
do m=1 for L; $= /*for all lengths, find a unique abbrev*/
do k=1 to #; a=left(@.k, m) /*get an abbreviation (with length M).*/
if wordpos(a,$)\==0 then iterate M /*test this abbreviation for uniquness.*/
$=$ a /*so far, it's unique; add to the list.*/
end /*k*/
leave m /*a good abbreviation length was found.*/
end /*m*/
return m

View file

@ -0,0 +1,18 @@
#lang racket
(require racket/set)
(define (abbr-length ss)
(for*/first ((l (in-range 1 (string-length (argmax string-length ss))))
#:when (equal? (sequence-length
(for/set ((s ss))
(substring s 0 (min l (string-length s)))))
(length ss)))
l))
(module+ main
(define report-line
(match-lambda
["" ""]
[(and s (app string-split ss)) (format "~a ~a" (abbr-length ss) s)]))
(for-each (compose displayln report-line) (take (file->lines "data.txt") 5)))

View file

@ -0,0 +1,8 @@
sub auto-abbreviate ( Str $string ) {
return Nil unless my @words = $string.words;
return $_ if @words».substr(0, $_).Set == @words for 1 .. @words».chars.max;
return '';
}
# Testing
say ++$, ') ', .&auto-abbreviate, ' ', $_ for './DoWAKA.txt'.IO.lines;

View file

@ -0,0 +1,30 @@
Red []
;; read and convert data to a string - to char conversion is neccessary to avoid
;; illegal utf8 encoding error....
data: collect/into [foreach b read/binary %abbrev.txt [keep to-char b ]] ""
;; data: read %abbrev.txt - would work, if file was utf-8 encoded ...
foreach line split data newline [ ;; split data in lines at carriage return & line feed:
if empty? trim line [ continue ] ;; continues at head of loop
arr: split line space ;; now split line in words ; accumulate in array / series
min: 1 ;; preset min length
until [
;; head is the first position of series
if head? arr [m: make map! [] ] ;; define an empty map (key -value store)
abbr: copy/part first arr min ;; copy/part ~ leftstr of first word with length min
arr: either m/:abbr [ ;; abbreviation already exists ?
min: min + 1
head arr ;; reset series position to head
][ ;; otherwise ....
m/:abbr: true ;; mark abreviation in map as existent
next arr ;; set series position to next word
]
tail? arr ;; this is the until condition , end /tail of series reached ?
]
print [min line] ;; print automatically reduces all words in block
]

View file

@ -0,0 +1,7 @@
require "abbrev"
File.read("daynames.txt").each_line do |line|
next if line.strip.empty?
abbr = line.split.abbrev.invert
puts "Minimum size: #{abbr.values.max_by(&:size).size}", abbr.inspect, "\n"
end

View file

@ -0,0 +1,53 @@
/**
* Abbreviations from tintenalarm.de
*/
use std::fs::File;
use std::io;
use std::io::{BufRead, BufReader};
fn main() {
let table = read_days("weekdays.txt").expect("Error in Function read_days:");
for line in table {
if line.len() == 0 {
continue;
};
let mut max_same = 0;
for i in 0..(line.len() - 1) {
for j in i + 1..line.len() {
max_same = max_same.max(begins_with_num_same_chars(&line[i], &line[j]));
}
}
println!("{}\t{:?}", max_same + 1, line);
}
}
fn read_days(filename: &str) -> io::Result<Vec<Vec<String>>> {
let f = File::open(filename)?;
let reader = BufReader::new(f);
let mut table: Vec<Vec<String>> = Vec::new();
for line in reader.lines() {
let mut days: Vec<String> = Vec::with_capacity(7);
for day in line?.split_whitespace() {
days.push(day.to_string());
}
table.push(days);
}
Ok(table)
}
fn begins_with_num_same_chars(str_a: &str, str_b: &str) -> u32 {
let mut num = 0;
for (pos, char_a) in str_a.chars().enumerate() {
match str_b.chars().nth(pos) {
Some(char_b) => {
if char_a == char_b {
num = num + 1;
} else {
return num;
}
}
None => return num,
}
}
num
}

View file

@ -0,0 +1,7 @@
name := "Abbreviations-automatic"
scalaVersion := "2.13.0"
version := "0.1"
homepage := Some(url("http://rosettacode.org/wiki/Abbreviations,_automatic#Scala"))
libraryDependencies += "com.lihaoyi" %% "os-lib" % "0.3.0"

View file

@ -0,0 +1,23 @@
object AbbreviationsAuto extends App {
private val wd = os.pwd
def processLine(line: String): String = {
if (line.nonEmpty) {
val days = line.split(' ')
val maxL = days.map(_.length).max
val paddedNames = days.map(s => s.padTo(maxL, ' '))
def uniqueN = (1 to maxL) // distinct filters uniques
.map(n => paddedNames.map(_.substring(0, n)).distinct)
.filter(_.size == paddedNames.length) // `.distinct` filters uniques
.head.head.length
f"$uniqueN%3d $line" // Return by means of String Interpolation
} else " \"\""
}
os.read.lines(wd / "days_of_week.txt")
.distinct
.foreach(line => println(processLine(line)))
}

View file

@ -0,0 +1,18 @@
function AbbreviationsAutomatic days
put 1 into abbreviationLength
put the number of items in days into len
repeat forever
put () into abbreviations
repeat with each item day in days
put the first abbreviationLength characters of day into abbreviation
if abbreviations contains abbreviation
exit repeat
end if
insert abbreviation after abbreviations
if the number of items in abbreviations is len
return abbreviationLength
end if
end repeat
add 1 to abbreviationLength
end repeat
end AbbreviationsAutomatic

View file

@ -0,0 +1,22 @@
put "Weekdays.txt" into myFile
put the defaultStringEncoding into savedEncoding
put "WinLatin1" into the defaultStringEncoding
open file myFile
repeat forever
read from file myFile until return
if it is empty then exit repeat
split trim(it) by " "
if the number of items in it is 0
put ""
else
put AbbreviationsAutomatic(it) && it
end if
end repeat
close file myFile
put savedEncoding into the defaultStringEncoding

View file

@ -0,0 +1,96 @@
STRING PROC FNStringGetExpressionRegularCharacterMetaEscapeS( STRING inS )
STRING s[255] = inS
s = StrReplace( "\", s, "\\", "gn" )
s = StrReplace( "{", s, "\{", "gn" )
s = StrReplace( "[", s, "\[", "gn" )
s = StrReplace( "}", s, "\}", "gn" )
s = StrReplace( "]", s, "\]", "gn" )
s = StrReplace( "*", s, "\*", "gn" )
s = StrReplace( "+", s, "\+", "gn" )
s = StrReplace( "@", s, "\@", "gn" )
s = StrReplace( ".", s, "\.", "gn" )
s = StrReplace( "^", s, "\^", "gn" )
s = StrReplace( "$", s, "\$", "gn" )
s = StrReplace( "|", s, "\|", "gn" )
s = StrReplace( "?", s, "\?", "gn" )
s = StrReplace( "#", s, "\#", "gn" )
RETURN( s )
END
//
INTEGER PROC FNBlockGetAbbreviationLengthMinimumToBufferB( INTEGER buffer1I )
INTEGER B = FALSE
INTEGER downB = TRUE
STRING s[255] = ""
INTEGER foundB = FALSE
INTEGER minI = 1
INTEGER I = 0
INTEGER buffer2I = 0
STRING s1[255] = ""
INTEGER lineColumnStartI = 4 // change this
Set( BREAK, ON )
PushPosition()
PushBlock()
GotoBlockBegin()
WHILE ( ( IsCursorInBlock() ) AND ( downB ) )
IF NOT LFind( "^$", "cgx" )
I = minI - 1
REPEAT
I = I + 1
PushPosition()
buffer2I = CreateTempBuffer()
PopPosition()
BegLine()
REPEAT
IF ( LFind( "{.*}{{[ ]#}|$}\c", "cx" ) )
s = GetFoundText( 1 )
s = Trim( s )
s1 = LeftStr( s, I )
PushPosition()
PushBlock()
GotoBufferId( buffer2I )
foundB = LFind( Format( "^", FNStringGetExpressionRegularCharacterMetaEscapeS( s1 ), "$" ), "gx" )
IF NOT foundB
EndFile()
AddLine( s1 )
ENDIF
PopBlock()
PopPosition()
ENDIF
UNTIL ( ( ( CurrChar() == _AT_EOL_ ) OR ( CurrChar() == _BEYOND_EOL_ ) ) OR ( foundB ) )
AbandonFile( buffer2I )
UNTIL ( NOT ( foundB ) )
ENDIF
IF NOT foundB
PushPosition()
PushBlock()
BegLine()
UnMarkBlock()
MarkStream()
EndLine()
Left()
MarkStream()
Copy()
GotoBufferId( buffer1I )
EndFile()
AddLine( Str( I ) )
GotoColumn( lineColumnStartI )
Paste()
PopBlock()
PopPosition()
ENDIF
downB = Down()
ENDWHILE
B = TRUE
PopPosition()
PopBlock()
RETURN( B )
END
//
PROC Main()
INTEGER bufferI = 0
PushPosition()
bufferI = CreateTempBuffer()
PopPosition()
Message( FNBlockGetAbbreviationLengthMinimumToBufferB( bufferI ) )
GotoBufferId( bufferI )
END

View file

@ -0,0 +1,18 @@
set f [open abbreviations_automatic_weekdays.txt]
set lines [split [read -nonewline $f] \n]
close $f
foreach days $lines {
if {[string length $days] == 0} continue
if {[llength $days] != 7} {
throw ERROR {not 7 days in a line}
}
if {[llength [lsort -unique $days]] != 7} {
throw ERROR {not all 7 days in a line are distinct}
}
for {set i 0} {1} {incr i} {
if {[llength [lsort -unique [lmap x $days {string range $x 0 $i}]]] == 7} break
}
incr i
puts "$i $days"
}

View file

@ -0,0 +1,13 @@
#lang transd
MainModule : {
_start: (λ
(with fs FileStream() words String()
(open-r fs "D:\\Temp\\wordlist.txt")
(for line in (read-lines fs) do
(with days (split line " ") len 0
(for w in days do (for y in days do
(if (neq w y) (= len (max len (coincide w y))))))
(lout (+ len 1) " " days))
) ) )
}

View file

@ -0,0 +1,59 @@
import os
fn distinct_strings(strs []string) []string {
len := strs.len
mut set := map[string]bool{}
mut distinct := []string{cap: len}
for str in strs {
if str !in set {
distinct << str
set[str] = true
}
}
return distinct
}
fn take_runes(s string, n int) string {
mut i := 0
for j in 0..s.len {
if i == n {
return s[..j]
}
i++
}
return s
}
fn main() {
lines := os.read_lines('days_of_week.txt')?
mut line_count := 0
for l in lines {
mut line := l
line = line.trim(' ')
line_count++
if line == "" {
println('')
continue
}
days := line.split(' ')
if days.len != 7 {
println("There aren't 7 days in line $line_count")
return
}
if distinct_strings(days).len != 7 { // implies some days have the same name
println(" ∞ $line")
continue
}
for abbrev_len := 1; ; abbrev_len++ {
mut abbrevs := []string{len: days.len}
for i := 0; i < days.len; i++ {
abbrevs[i] = take_runes(days[i], abbrev_len)
}
if distinct_strings(abbrevs).len == 7 {
println("${abbrev_len:2} $line")
break
}
}
}
}

View file

@ -0,0 +1,19 @@
Function MinimalLenght(strLine As String) As Integer
Dim myVar As Variant, I As Integer, Flag As Boolean, myColl As Collection, Count As Integer
myVar = Split(strLine, " ")
Count = 0
Do
Set myColl = New Collection
Count = Count + 1
On Error Resume Next
Do
myColl.Add Left$(myVar(I), Count), Left$(myVar(I), Count)
I = I + 1
Loop While Err.Number = 0 And I <= UBound(myVar)
Flag = Err.Number = 0
On Error GoTo 0
I = 0
Set myColl = Nothing
Loop While Not Flag
MinimalLenght = Count
End Function

View file

@ -0,0 +1,16 @@
Sub Main_Abbr_Auto()
Dim Nb As Integer, s As String, Result() As String, c As Integer
Nb = FreeFile
Open "C:\Users\" & Environ("Username") & "\Desktop\Abbreviations_Auto.txt" For Input As #Nb
While Not EOF(Nb)
Line Input #Nb, s
If InStr(s, "þ") > 0 Then s = Right(s, Len(s) - 2)
If s <> vbNullString Then
ReDim Preserve Result(c)
Result(c) = Left$(MinimalLenght(s) & " ", 4) & s
Debug.Print Result(c)
c = c + 1
End If
Wend
Close #Nb
End Sub

View file

@ -0,0 +1,36 @@
sub print(s) wscript.stdout.writeline s :end sub
set d=createobject("Scripting.Dictionary")
set fso=createobject("Scripting.Filesystemobject")
const fn="weekdays_ansi.txt"
sfn=WScript.ScriptFullName
sfn= Left(sfn, InStrRev(sfn, "\"))
set f=fso.opentextfile(sfn & fn,1)
while not f.atendofstream
s=f.readline
if s=vbNullString then
print " "
else
a=split(trim(s)," ")
for abrlen=1 to 14
d.removeall
for wd=0 to 6
k=left(a(wd),abrlen)
if d.exists(k) then
exit for
else
d.add k,""
end if
next 'wd
if wd>6 then exit for
next 'abrlen
b=right(" " & abrlen,2)
for wd=0 to 6
b=b &" "& left(a(wd),abrlen)
next
print b
end if
wend 'line
f.close

View file

@ -0,0 +1,49 @@
Module Module1
Sub Main()
Dim lines = IO.File.ReadAllLines("days_of_week.txt")
Dim i = 0
For Each line In lines
i += 1
If line.Length > 0 Then
Dim days = line.Split()
If days.Length <> 7 Then
Throw New Exception("There aren't 7 days in line " + i)
End If
Dim temp As New Dictionary(Of String, Integer)
For Each d In days
If temp.ContainsKey(d) Then
Console.WriteLine(" ∞ {0}", line)
Continue For
End If
temp.Add(d, 1)
Next
Dim len = 1
Do
temp.Clear()
For Each d In days
Dim key As String
If len < d.Length Then
key = d.Substring(0, len)
Else
key = d
End If
If temp.ContainsKey(key) Then
Exit For
End If
temp.Add(key, 1)
Next
If temp.Count = 7 Then
Console.WriteLine("{0,2:D} {1}", len, line)
Exit Do
End If
len += 1
Loop
End If
Next
End Sub
End Module

View file

@ -0,0 +1,29 @@
import "io" for File
import "/pattern" for Pattern
import "/seq" for Lst
import "/fmt" for Fmt
var p = Pattern.new("+1/s")
var lines = File.read("days_of_week.txt").split("\n").map { |l| l.trim() }
var i = 1
for (line in lines) {
if (line == "") {
if (i != lines.count) System.print()
} else {
var days = p.splitAll(line)
if (days.count != 7) Fiber.abort("There aren't seven days in line %(i).")
if (Lst.distinct(days).count < 7) { // implies some days have the same name
System.print(" ∞ %(line)")
} else {
var len = 1
while (true) {
if (Lst.distinct(days.map { |d| d.take(len).join() }.toList).count == 7) {
Fmt.print("$2d $s", len, line)
break
}
len = len + 1
}
}
}
i = i + 1
}

View file

@ -0,0 +1,28 @@
a = open("days_of_week.txt", "r")
while(not eof(#a))
line input #a s$
print buscar(s$), " ", s$
wend
close #a
sub buscar(s$)
local n, d, i, j, s, a$, b$, r$(1)
n = token(s$, r$())
d = 1
repeat
s = true
for i = 1 to n
for j = i + 1 to n
a$ = left$(r$(i), d)
b$ = left$(r$(j), d)
if a$ = "" or b$ = "" s = true : break 2
if a$ = b$ s = false : d = d + 1 : break 2
next
next
until(s)
return d
end sub

View file

@ -0,0 +1,11 @@
nds:=File("daysOfWeek.txt").read().howza(11) // stripped lines
.pump(List,Void.Filter,fcn(day){
d,N,m := day.split(),d.len(),(0).max(d.apply("len")); // N==7
foreach n in ([1..m]){
ds:=d.apply("get",0,n); // ("Su","Mo","Tu","We","Th","Fr","Sa")
foreach a,b in (N,[a+1..N-1]){ if(ds[a]==ds[b]) continue(3); } # Th==Fr?
return(n,day); // part way though the words and found unique
}
return(m,day); // no match nowhere
});
foreach n,s in (nds){ println("%3d %s".fmt(n,s)); }