Neulich haben wir mit meiner Tochter Sätze mit einem Kühlschrankmagneten geschrieben. Während wir einige ( I love cat
) erstellen konnten , hatten wir nicht genügend Buchstaben, um die anderen ( I love you too
) zu erstellen, da die Anzahl der Buchstaben nicht ausreicht o
(4).
Ich fand dann heraus, dass ein Satz, der 3 e
Buchstaben enthielt, nur 2 o
Buchstaben hatte. Wahrscheinlich inspiriert von http://en.wikipedia.org/wiki/Letter_frequency würde dies immer noch nicht die tatsächliche Situation "auf dem Kühlschrank" widerspiegeln.
Problem
In Anbetracht der Textdatei, in der jede Zeile einen "Beispielsatz" enthält, den man auf den Kühlschrank schreiben möchte, schlagen Sie ein Alphabet mit einer Mindestanzahl von Buchstaben vor, das jedoch immer noch ausreicht, um jeden Satz einzeln zu schreiben.
Hinweis: Groß- und Kleinschreibung ignorieren, alle Magnetbuchstaben sind trotzdem Großbuchstaben.
Eingang
Die Datei enthält durch Zeilenumbrüche getrennte Sätze:
hello
i love cat
i love dog
i love mommy
mommy loves daddy
Ausgabe
Geben Sie eine sortierte Liste von Buchstaben an, wobei jeder Buchstabe nur so oft vorkommt, dass er ausreicht, um einen Satz zu schreiben:
acdddeghillmmmoostvyy
(danke isaacg!)
Gewinner
Kürzeste Implementierung (Code)
AKTUALISIERT: Testen
Ich habe einen extra Test erstellt und hier mit verschiedenen Antworten versucht:
v
Die Ausgabe sollte einen Brief enthalten ;)M
für einW
oder ein seitlichesN
für ein ersetzenZ
? ;-)I
s konstruieren ._\¯
Antworten:
GolfScript, 28/34 Zeichen
Das obige 28-stellige Programm geht davon aus, dass alle eingegebenen Buchstaben gleich sind. Wenn dies nicht unbedingt der Fall sein muss, können wir sie durch Voranstellen
{95&}%
des Codes in Großbuchstaben umwandeln. Dies ergibt insgesamt 34 Zeichen:Anmerkungen:
Für einen korrekten Betrieb muss die Eingabe mindestens eine neue Zeile enthalten. Dies gilt für normale Textdateien mit Zeilenumbrüchen am Ende jeder Zeile. Dies gilt jedoch möglicherweise nicht, wenn die Eingabe nur aus einer Zeile ohne abschließende Zeilenumbrüche besteht. Dies könnte auf Kosten von zwei zusätzlichen Zeichen durch Voranstellen
n+
des Codes behoben werden.Die in der 34-stelligen Version verwendeten Großbuchstaben sind sehr grob - sie ordnen Kleinbuchstaben in ASCII-Zeichen den entsprechenden Großbuchstaben (und Leerzeichen in
NUL
s) zu, führen jedoch zu einem völligen Durcheinander von Zahlen und den meisten Interpunktionszeichen. Ich gehe davon aus, dass die Eingabe keine solchen Zeichen enthält.Die 28-stellige Version behandelt alle eingegebenen Zeichen (mit Ausnahme von Zeilenumbrüchen und
NUL
s) gleich. Insbesondere wenn die Eingabe Leerzeichen enthält, werden einige auch in der Ausgabe angezeigt. Bequemerweise werden sie vor allen anderen druckbaren ASCII-Zeichen sortiert. Die 34-stellige Version ignoriert jedoch Leerzeichen (da sich herausstellt, dass ich das tun kann, ohne dass es mich zusätzliche Zeichen kostet).Erläuterung:
Das optionale
{95&}%
Präfix übersteigt die Eingabe, indem das sechste Bit des ASCII-Codes jedes Eingangsbytes ( ) auf Null gesetzt wird . Dadurch werden ASCII-Kleinbuchstaben in Großbuchstaben, Leerzeichen in Nullbytes und Zeilenumbrüche unverändert übernommen.95 = 64 + 31 = 10111112
n/
Teilt die Eingabe in Zeilenumbrüche und:a
weist das resultierende Array der Variablen zua
.{|}*
Berechnet dann die Mengenvereinigung der Zeichenfolgen im Array, die (unter der Annahme, dass das Array mindestens zwei Elemente enthält) eine Zeichenfolge ergibt, die alle eindeutigen Zeichen (ohne Zeilenumbruch) in der Eingabe enthält.Die folgende
{ }%
Schleife durchläuft dann jedes dieser eindeutigen Zeichen. Innerhalb des Schleifenkörpers durchläuft die innere Schleifea{.[2$]--}%
die Zeichenfolgen im Arraya
und entfernt aus jeder Zeichenfolge alle Zeichen, die nicht mit den Zeichen übereinstimmen, über die die äußere Schleife iteriert.Die innere Schleife belässt den ASCII-Code des aktuellen Zeichens auf dem Stapel unterhalb des gefilterten Arrays. Wir machen uns das zunutze, indem wir das gefilterte Array so oft wiederholen, wie es durch den ASCII-Code (
*
) angegeben ist, bevor$
wir es sortieren ( ) und das letzte Element nehmen (-1=
). Tatsächlich ergibt dies die längste Zeichenfolge im gefilterten Array (da sie alle aus Wiederholungen desselben Zeichens bestehen, sortiert die lexikografische Sortierung sie nur nach Länge), es sei denn, das Zeichen hat den ASCII-Code Null. In diesem Fall ergibt sie nichts.Schließlich
$
sortiert die am Ende nur die Ausgabe alphabetisch.quelle
n/:a{|}*{{{=}+,}+a%$-1=}%$
.J - 37 Zeichen
Liest von stdin, gibt auf Konsole aus.
1!:1]3
ist der Ruf nach stdin.tolower;._2
Führt eine doppelte Aufgabe aus, indem die Zeilen aufgeteilt und gleichzeitig in Kleinbuchstaben umgewandelt werden. Dann zählen wir mit, wie oft ein Zeichen in jeder Zeile vorkommt+/"2=/&a.
, und nehmen mit das punktweise Maximum über alle Zeilen>./
.Schließlich ziehen wir so viele Zeichen aus dem Alphabet mit
#&a.
. Dies schließt Leerzeichen ein, die alle aufgrund ihres niedrigen ASCII-Werts vorne zu finden sind. Deshalb löschen wir nur führende Leerzeichen mitdlb
.quelle
JavaScript (ECMAScript 6) -
148139135 ZeichenVersion 2:
Aktualisiert, um das Array-Verständnis zu verwenden:
Version 1:
Angenommen, dass:
s
.Mit Kommentaren:
Wenn du möchtest:
.join('')
am Ende hinzu.s
Variable durchprompt()
; oderf
und fügen Sief=s=>
es am Anfang hinzu.Laufen:
Gibt die Ausgabe aus:
quelle
/\s*/
,/ */
indem Sie die Parens umj=0
...
anstelle von verwendenapply
?...
) -Operator einer, dem ich noch nie begegnet bin.[].concat(...s.split`N`.map(x=>x.split(/ */).map((x,i,a)=>x+(a[x]=a[x]?++j:j=1)))).sort().map((x,i,a)=>a[i-1]<x?x[0]:'').join``;
Perl - 46 Bytes
Zählen Sie den Shebang als 1. Dies ist eine lose Übersetzung der Ruby-Lösung unten.
Ruby 1,8 - 72 Bytes
Die Eingabe wird von übernommen
stdin
.Beispielnutzung:
quelle
/i
undfor
.Python -
2062041991771451291179488 ZeichenIch war mir nicht sicher, wie ich den Dateinamen erhalten sollte, daher geht der Code im Moment davon aus, dass er in einer Variablen namens enthalten ist
f
. Bitte lassen Sie mich wissen, wenn ich das ändern muss.quelle
f
den Dateinamen für die Eingabe übernehmen und Großbuchstaben verwenden (alle Magnetbuchstaben sind ohnehin Großbuchstaben), können Sie 91:print(''.join([chr(i)*max(l.upper().count(chr(i))for l in open(f))for i in range(65,91)]))
Ruby 1.9+, 51 (oder 58 oder 60)
Nimmt an, dass alles in Kleinbuchstaben geschrieben ist.
.upcase
Groß- und Kleinschreibung kostet 7 Zeichen via , während Groß- und Kleinschreibung 9 Zeichen via kostet.downcase
.quelle
R (156, inkl. Datei lesen)
Mit table konstruiere ich für jeden Satz die Buchstabenhäufigkeitstabelle. Am Ende nehme ich für jeden Buchstaben den Maximalwert.
Ungolfed:
Lösung:
quelle
a=unlist(lapply(readLines(fn),function(x)table(strsplit(tolower(x),""))));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")
, aber es ist nur 3 Zeichen kürzercat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")
annehmen , dassf
der DateinameHaskell,
109108Das Programm liest von stdin und schreibt nach sdtout.
Es ist ganz einfach: Es zerlegt die Zeichenfolge in eine Liste von Zeilen und erstellt sie neu, indem es in der Liste iteriert und die neuen Buchstaben in jeder Zeile hinzufügt.
quelle
Perl 6:
5653 Zeichen;5855 BytesFür jede Zeile wird diese für die Nicht-Leerzeichen der Zeichenfolge in Kleinbuchstaben (
comb /\S/,.lc
) durchkämmt , und es wird einBag
oder eine Auflistung jedes Zeichens erstellt und wie oft es auftritt.[∪]
Führt die Vereinigung derBag
s über alle Zeilen aus, wodurch die maximale Häufigkeit des Auftretens des Zeichens ermittelt wird..pick(*)
ist hack-y hier, aber es ist der kürzeste Weg, um alle Zeichen aus demBag
replizierten zu bekommen, wie oft es aufgetreten ist.EDIT: Um zu sehen, ob es kürzer wäre, habe ich versucht, die Ruby-Antwort des Histokraten zu übersetzen . Es sind 63 Zeichen, aber mir gefällt der Ansatz immer noch sehr gut:
quelle
Haskell,
183 162159Vorausgesetzt, die Datei ist in
file.txt
!Wenn file.txt zum Beispiel enthält
Das Skript wird ausgegeben
Grundsätzlich hänge ich das gesamte Alphabet an jede Zeile an, sodass ich beim Gruppieren und Sortieren sicher eine Liste mit 27 Elementen erhalte. Als nächstes transponiere ich die "Häufigkeitstabelle", so dass jede Zeile in diesem Array aus den Häufigkeiten eines einzelnen Buchstabens in jeder Zeile besteht, z
["a","","aaa","aa","aaaa"]
. Ich wähle dann das Maximum jedes Arrays (was genau so funktioniert, wie ich es möchte, weil dieOrd
-Instanz von Strings funktioniert), lasse den Buchstaben fallen, den ich am Anfang angehängt habe, entferne die Leerzeichen und gebe das Ergebnis aus.quelle
drop 1
Verwendentail
C 99 Zeichen
Es stürzt ab, wenn weniger als eine neue Zeile angegeben wird. Ich denke, es könnte ganz einfach behoben werden.
quelle
kdb (q / k): 59 Zeichen:
-1 fügt eine neue Zeile hinzu, mit 1 wird ein Zeichen gespeichert, die angegebene Ausgabe wird jedoch nicht generiert. Ich wünschte, ich könnte die .z.pi / .z.exit-Kesselplatte entfernen, die 14 Zeichen entfernt.
Bearbeiten: Vermeiden Sie die Verwendung von inter / asc, indem Sie das Startwörterbuch verwenden.
quelle
Perl, 46
Hier ist eine andere Perl-Lösung, die von STDIN gelesen wird, einen
-n
Schalter (+1 zum Zählen) erfordert , mit Primos Punktzahl in Verbindung steht, aber ohne Beschwerden läuft :-). Dabei wird die Tatsache ausgenutzt, dassor
das Ergebnis von bitwise eine längere Länge für Zeichenfolgenargumente hat.quelle
Ich füge meine eigene Lösung hinzu:
Bash - 72
Angenommen, die Eingabe befindet sich in der Datei "i".
Erläuterung
Filtert es für jeden möglichen Buchstaben nur aus der Eingabedatei heraus, was ungefähr so aussieht:
Das Ergebnis wird sortiert und die längste Zeile ausgewählt.
echo -n
ist da, um Zeilenumbrüche zu entfernen.quelle
Bash,
171159158, 138 mit Junk-AusgabeBenötigt nur Kleinbuchstaben. Angenommen, die Datei heißt
_
(Unterstrich). Maximal 26 Zeilen in der Eingabedatei aufgrund der lästigen Dateinamensplit
(xaa, xab ... xaz, ???).In
bash
,{a..z}
Ausgängea b c d e f ...
.Beispielausgabe
Erläuterung
Erstellen Sie Dateien, die wir später lesen werden, damit sich Bash nicht beschwert, dass sie nicht existieren. Wenn Sie diese Zeile entfernen, sparen Sie 13 Zeichen, erhalten aber viel Junk-Ausgabe.
Teilen Sie die Eingabedatei in Abschnitte auf, in denen jeweils 1 Zeile gespeichert ist. Die Dateien, die dieser Befehl erstellt, heißen xaa, xab, xac usw. Ich habe keine Ahnung, warum.
$l
Lesen Sie für jeden Buchstaben alle in Dateien gespeicherten Zeilen durchxa$s
.Entfernen Sie den
-s
Schalter, um 1 Zeichen zu sparen und viel Junk-Output zu erhalten. Es verhindert, dass Siegrep
sich über nicht vorhandene Dateien beschweren (dies geschieht, wenn Sie nicht über 26 Eingabezeilen verfügen). Dadurch wird die Datei verarbeitetxa$s
, alles andere als Vorkommen entfernt$l
und die Ausgabe an die Datei gesendetb$l
. Also wird "i love mommy" zu "mmm" mit neuen Zeilen nach jedem Buchstaben, wenn$l
m ist.Wenn die Anzahl der Zeilen in der soeben erstellten Datei größer oder gleich der Anzahl der Zeilen in unserem höchsten Ergebnis ist (gespeichert in
$l
) ...... speichern Sie unseren neuen Datensatz in der Datei
$l
. Am Ende dieser Schleife, wenn wir alle Zeilen durchlaufen haben, werden in der Datei$l
x Zeilen gespeichert, die jeweils den Buchstaben enthalten$l
, wobei x die höchste Anzahl von Vorkommen dieses Buchstabens in einer einzelnen Zeile ist.Geben Sie den Inhalt unserer Datei für diesen bestimmten Buchstaben aus und entfernen Sie dabei neue Zeilen. Wenn Sie die neuen Zeilen nicht entfernen möchten, ändern Sie die Zeile mit
tr
aufecho $l
, und sparen Sie 6 Zeichen.quelle
split
(als coreutils). Ich verwende derzeit GNU bash 4.3.8 und GNU coreutils 8.21 unter Ubuntu 14.04 und es funktioniert einwandfrei (es hat auch unter Ubuntu 13.10 funktioniert, bevor ich ein Upgrade durchgeführt habe). Allerdings musste ich das Programm und die Eingabedatei in einem separaten Verzeichnis ablegen, damit es ordnungsgemäß funktioniert. Ich vermute, dass dies nur auf die Millionen von Junk-Dateien in meinem privaten Ordner zurückzuführen war .split _ -l1
und feststellen, dass Ihre Eingabe in gespeichert-l1aa
wird, wird Ihre Version von meiner Meinung nachsplit
nicht-l1
als Option erkannt , sondern als Präfix für die Ausgabe . Versuchen Sie, ein Leerzeichen zwischen-l
und1
, oder Putting--lines=1
oder einfach nur-1
(dies scheint eine veraltete und mehr Golf-Syntax zu sein, mit der ich den Beitrag jetzt aktualisieren werde).C # 172 Bytes
quelle
Python 2 - 129
Idee von @Tal
Ein paar weitere Möglichkeiten, um dasselbe mit der gleichen Anzahl von Zeichen zu tun:
Dies setzt voraus, dass die Datei als f in einem Verzeichnis gespeichert ist, auf das zugegriffen werden kann. Dieses Programm kann direkt ausgeführt werden, ohne dass zusätzliche Eingaben erforderlich sind.
quelle
Mathematica v10 - 110
Es ist noch nicht fertig, aber ich lese die neue Dokumentation sehr sorgfältig durch. Ich denke, das sollte funktionieren:
quelle
Scala, 125 Zeichen
Zuerst las ich die Eingabe, wandelte sie in Kleinbuchstaben um und fügte eine leere Zeile hinzu.
Dann wiederhole ich diesen Buchstaben für jeden Buchstaben von
a
bisz
maximal so oft, wie er in einer der Zeilen vorkommt (deshalb brauche ich die leere Zeile:max
kann bei einer leeren Eingabe nicht aufgerufen werden). Dann verbinde ich einfach die Ergebnisse und drucke auf die Ausgabe.Zum Lesen aus einer Datei, ersetzen
stdin
mitfromFile("FILENAME")
, die Erhöhung der Größe des Codes zu 132 Zeichen + Dateiname Länge.quelle
Javascript, 261 Zeichen
Entfernen Sie den Befehl
eval(...)
und führen Sie ihn aus, um den tatsächlichen Code zu erhalten. das ist ( etwas ) komprimiert.s
Multifunktional als Zeilenarray und als ausgegebener String,h
enthält das Histogramm der Buchstaben pro Zeile undH
enthält das Histogramm mit den bisherigen Maximalwerten. Die Groß- und Kleinschreibung wird nicht beachtet und alles außer az und AZ wird ignoriert (ich denke ... JS-Arrays sind manchmal komisch).Jetzt richtig :)
quelle
@
bis ich zum Ende kam. Ich mag es :)JavaScript ( ES5 ) 141 Byte
Angenommen, die Variable
s
ist die Eingabezeichenfolge ohne Anforderungen für die Fallprüfung und Array-Ausgabe:quelle
PowerShell - 141
Liest Text aus einer Datei mit dem Namen 'a'.
quelle
Groovy,
113/127102/116 ZeichenAngenommen, die Datei ist alles in einem Fall (102 Zeichen):
Angenommen, die Datei enthält gemischte Groß- / Kleinschreibung (116 Zeichen):
Grundsätzlich gilt:
t=new File('f').text
Um den Text der Datei zu erhalten.t.findAll('[A-Z]').unique().sort().each{c->
Um die eindeutigen Zeichen zu erhalten, sortieren Sie sie und wiederholen Sie sie.print c*t.readLines()*.count(c).max()
Holen Sie sich die maximalen Vorkommen in einer einzigen Zeile und drucken Sie das Zeichen so oft.quelle
Bash (meistens awk) -
172163157Text muss an awk weitergeleitet werden (oder als Datei angegeben werden).
Beispiel Eingabe
Beispielausgabe
PHP (könnte wahrscheinlich besser sein) -
174210Angenommen, die Zeichenfolge ist in der Variablen $ s enthalten
Beispiel Eingabe
Beispielausgabe
quelle
Mir ist klar, dass dies wahrscheinlich nicht die effizienteste Antwort ist, aber ich wollte trotzdem versuchen, das Problem zu lösen. Hier ist meine ObjC-Variante:
Dann können Sie es für eine beliebige Zeichenfolge aufrufen:
Ich habe über Anwendungen mit größeren Textmengen nachgedacht und möchte mein Array lieber nicht zählen müssen. Dazu habe ich die Methode folgendermaßen erweitert:
Laufen Sie wie folgt:
Werde dir geben:
Was ich für besser halte, wenn ich sehr viel Text hätte und nur wissen müsste, wie viele von jedem Buchstaben ich brauchen würde.
quelle
K, 34
quelle
Python 2, 154 Bytes
quelle
s
Am Ende derimport
Anweisung fehlt ein und imwith
Block fehlt die Einrückung. Und da es sich um Codegolf handelt, ist es von großem Vorteil, unnötige Leerzeichen zu entfernen, wenn dies möglich ist.C 298 Bytes
Array D enthält eine Buchstabenliste für jede Zeile, dann wird die maximale Anzahl nach C kopiert.
Hinweis: Ich habe meine Antwort gestern eingegeben, sie ist jetzt jedoch nicht aufgeführt. Vielleicht habe ich versehentlich auf Löschen geklickt, anstatt sie zu bearbeiten.
quelle
int
vonint main()
und weglassenint j,n;
.PHP, 143 Bytes
Angenommen, die Eingabe wird in Variable übergeben
$s
:Erläuterung
Für jeden möglichen Buchstaben ordne ich ein Array mit einer Liste von Zeichenfolgen durch eine benutzerdefinierte Funktion zu, die jede Zeile durch die Anzahl der verwendeten Zeichen ersetzt. Für den Buchstaben 'd' wird die Zeile "Mama liebt Papa" in 3 abgebildet.
Danach finde ich den Maximalwert innerhalb des Arrays und des Ausgabebuchstabens nur so oft. Hier ist eine mehrzeilige Version:
quelle
Python (209, einschließlich Beispiel, 136 ohne.):
Ich werde heute Nachmittag eine PYG-Probe veröffentlichen.
quelle