LesezeichenAbonnierenRSS-Feed abonnieren
AndreasMenrath
Pyrite | Level 9

Hallo zusammen,

 

ich habe mir mal wieder eine neue Code Kata ausgedacht, bzw. mir diese interessante Kata aus http://codekata.com/kata/kata06-anagrams/ zur Übung herausgesucht.

Es geht darum aus einer simplen Liste an Wörtern alle Kombinationen herauszufinden, die ein Anagramm darstellen. Die Wortliste kann unter http://codekata.com/data/wordlist.txt heruntergeladen werden.

 

Diese Aufgabe ist anspruchsvoller als die vorherigen Katas, da man sich neben einigen Implementierungsdetails auch noch einen passenden Algorithmus ausdenken muss. Möglichst performant sollte dieser natürlich auch noch sein - und am besten auch noch kurz, leicht zu lesen und verstehen sowie wartbar. Also eine perfekte Aufgabe um die Zeit bis Weihnachten totzuschlagen und dabei etwas zu lernen 🙂

 

Als kleinen Tipp zum Start biete ich hier mal den ersten Codeschnipsel, um die Daten aus der Datei nach SAS einzulesen:

Spoiler
filename words URL "http://codekata.com/data/wordlist.txt" termstr=LF;

data words;
   length word $60;
   infile words encoding='wlatin1';
   input word $;
run;

Noch ein Hinweis für alle: das längste Wort ist 60 Zeichen lang.

 

Da ich auch bald Urlaub habe und niemandem die Lösung vorenthalten will, werde ich meine Lösung als Datei an diesen Post anhängen. Ich bin gespannt, ob jemand eine bessere Lösung findet. Wie immer sind Diskussionen sehr erwünscht.

 

Ich wünsche allen viel Spaß beim Knobeln und schöne Festtage!

 

Viele Grüße,

Andreas Menrath

2 ANTWORTEN 2
mfab
Quartz | Level 8

Hallo zusammen,

 

hier mal eine erste Lösung von mir:

 

options fullstimer;

/* Einlesen (hier unter University Edition, mit heruntergeladener Datei) */
data work.words;
   length word $60;
   infile "/folders/myfolders/wordlist.txt" encoding='wlatin1';
   input word $;
run;

/* Buchstaben fuer Abgleich in Reihenfolge bringen */
data work.words2 (keep=word myword laenge);
 set work.words end=eof;
  laenge = length(word);
  array buchstabensuppe{60} $;
  do n = 1 to laenge;
    buchstabensuppe{n} = substr(word,n,1);
  end;
  call sortc(of buchstabensuppe{*});
  myword = cats(of buchstabensuppe{*});
run;

/* Join, sodass alle Anagramme unter einem Schluessel "myword" stehen */
proc sql;
create table work.wordjoin as
select distinct a.myword, a.word
  from work.words2 a, work.words2 b
  where a.laenge = b.laenge
    and a.myword = b.myword
  order by myword
;quit;

/* Ausgabe der Anagramme pro Schluessel "myword" */
data work.ergebnis (keep=erg);
 set work.wordjoin;
 length erg $300;
 by myword;
  retain erg;
  if first.myword then erg = '';
  erg = catx(' ', erg, word);
  if last.myword and not first.myword then output;
run;

Ich würde das Ganze gerne generisch machen, sodass ich nicht die Länge 60 bei den Wörtern vorgebe.

Falls mir dazu jemand einen Tipp hat, bin ich gerne offen.

Abgesehen vom Einlesen scheitert das momentan daran, dass es offensichtlich nicht möglich ist, ein Array mit (nach Zeile) variabler Größe zu schaffen.

Ich würde gerne mit z.B. so etwas arbeiten: array meinArray{ length(irgendeineVariable) }

 

So und nun schaue ich mal in die bereitgestellte Lösung, ich bin mal gespannt, ob ich Ähnlichkeiten finde 🙂

 

Beste Grüße zu den Feiertagen!

Michael

AndreasMenrath
Pyrite | Level 9

Hallo Michael ( @mfab ),

Danke für deine Einsendung. Ja, die Ähnlichkeiten sehe ich deutlich, da mein Algorithmus fast genau so vorgeht.
Sogar deinen Join über die Länge hatte ich ursprünglich auch mit eingebaut, bis mir aufgefallen ist, dass das sortierte Wort (bei dir die Variable myword) als Joinkriterium ausreicht.

Zu deiner Frage: das ist leider eine Limitierung des Datasteps. Sobald der Datastep kompiliert ist und der Programm Daten Vektor (PDV) erzeugt wurde, kann man zur Laufzeit am PDV nichts mehr ändern, wie z.B. neue Variablen hinzuzufügen.

Ebenfalls frohe Festtage!
Andreas

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

Diskussionsstatistiken
  • 2 Antworten
  • 1560 Aufrufe
  • 2 Kudos
  • 2 in Unterhaltung