| Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann. |
Diskussion: Text->Brainfuck Konverter im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige Von Eydeet, nicht ganz trivial: Zitat: "Schreibe ein Programm, das einen eingegebenen Text möglichst kurz in BrainFuck-Code umsetzt". Es ...
![]() |
| | #1 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | Anzeige Von Eydeet, nicht ganz trivial: Zitat:
Statt Brainfuck können auch gerne andere Sprachen (Ook!, Whitespace) genommen werden.
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
| | #2 (permalink) |
| C++ sorry für die formatierung.. hatte hier nur notepad. achso: die Funktion AddText() gibt den Text in einem Richedit aus.. hatte da mal ne kleine IDE für Brainf*ck geschrieben | |
| | |
| HaBOT | - Anzeige - |
| |
| | #3 (permalink) |
| Registriert seit: 22.03.08 ![]() Likes: 0 | text2bfsource.c Wäre natürlich kürzer (also mein sourcecode), wenn ich die brainfuck-Source nicht in einem extra-Chararray halten würde, sondern einfach direkt ausgeben würde. Jetzt müsste ich nur noch drauf kommen, wie ich dem "so kurz wie möglich" (also in Bezug auf den generierten brainfuck-sourcecode) der Aufgabenstellung Rechnung tragen könnte. (Denn das ist ja der eigentliche "Witz" der Aufgabe.) Ich glaube der generierte brainfuck-code hat sogar so ziemlich die "worst-length". Mal schaun ob mich ne Idee überfällt. |
| | |
| | #4 (permalink) |
| Registriert seit: 14.04.06 ![]() Likes: 4 | Um das Problem zu lösen, habe ich mir zwei Strategien ausgedacht. Die erste (diff2bf_dumb) ist die einfachste, die vorstellbar ist. Sie addiert/subtrahiert einfach solange, bis die aktuelle Stelle den richtigen Wert hat, der dann ausgegeben wird. Die zweite (diff2bf_loop) ist schon etwas komplizierter, ist aber nur bei größeren Differenzen besser. Es werden Lösungen für die Formel "diff = a * b + c" gesucht, mit der Bedingung, dass "|a| + |b| + |c|" minimal werden soll. Mithilfe dieser Werte wird die benachbarte Zelle auf den Wert a gebracht, sodass in einer Schleife der Wert der Haupt-Zelle "a" mal um "b" verändert werden kann, anschließend wird "c" mal der nötige Operator verwandt; nicht jede Zahl lässt sich schließlich gut faktorisieren. Das Ergebnis ist schon mal ganz gut, es gibt aber sicher noch Optimierungspotential. Vielleicht wäre es sinnvoll, zwei Haupt-Zellen statt einer zu nutzen, wobei eine immer im niedrigen, und eine im hohen Bereich bleibt. Vor Allem bei häufigem Wechsel von Groß- und Kleinschreibung ist mein Algorithmus noch extrem ineffektiv. Mich würde interessieren, ob ihr noch Ideen habt (oder konkrete Umsetzungen). Mein Code darf auch gerne erweitert werden. Code: #!/usr/bin/python
import math
def diff2bf_dumb(diff):
op = ['+', '-'][diff < 0]
return op * abs(diff)
def bestFactors(N):
N = abs(N)
a = int(round(0.5 + math.sqrt(N)))
best = 10000000000
bestA = bestB = 0
while a > 1:
a -= 1
b = int(round(N/a))
val = a + b + abs(N-a*b)
if val < best:
bestA, bestB = a, b
best = val
return bestA, bestB, abs(N - bestA * bestB)
def diff2bf_loop(diff):
if diff == 0:
return ''
op = ['+', '-'][diff < 0]
a, b, c = bestFactors(diff)
code = '>' + '+' * a + '[<' + op * b + '>-]<' + op * c
return code
def diff2bf(diff):
strategies = [diff2bf_dumb, diff2bf_loop]
bestCode = ''
bestLen = 100000000
for s in strategies:
code = s(diff)
l = len(code)
if (l < bestLen):
bestCode = code
bestLen = l
return bestCode
def string2bf(s):
val1 = 0
result = ''
for c in list(s):
goal = ord(c)
diff = goal - val1
code = diff2bf(diff)
val1 = goal
result += code + '.\n'
return result
print string2bf("Hello, world!") Code: >++++++++[<+++++++++>-]<. >++++[<+++++++>-]<+. +++++++. . +++. >++++++[<----------->-]<-. ------------. >+++++++[<++++++++++++>-]<+++. --------. +++. ------. --------. >++++++[<----------->-]<-. |
| | |
| | #5 (permalink) |
![]() Registriert seit: 17.10.09 ![]() Likes: 10 | Ich habe vor einiger Zeit ein wenig mit genau der selben Aufgabe herumexperimentiert und habe mich dazu entschlossen alle auftretenden Zeichen on demand in einem Register zu speichern und diese dann nur noch auszugeben. Bei langen Texten funktiniert das ziemlich gut. Meine "Komprimierungsfunktion" ist allerdings noch nicht so prall Da werde ich wahrscheinlich teile von Eydeets code einbauen. Java code "Hello, World!" mit 346 Zeichen. Code: >+++++++[<++++++++++>-]<++. >>++++++++++[<++++++++++>-]<+. >>++++++++++[<++++++++++>-]<++++++++. . >>+++++++++++[<++++++++++>-]<+. >>++++[<++++++++++>-]<++++. >>+++[<++++++++++>-]<++. >>+++++++++++[<++++++++++>-]<+++++++++. <<<. >>>>>+++++++++++[<++++++++++>-]<++++. <<<<<. >>>>>>>++++++++++[<++++++++++>-]<. >>+++[<++++++++++>-]<+++. Geändert von Sleepprogger (10.10.11 um 16:45 Uhr) |
| | |
| | #6 (permalink) |
| Registriert seit: 05.12.11 ![]() Likes: 2 | Ich spiel auch nochmal kurz den Nekrophilen. Meine Lösung in Perl produziert zwar schrecklichen BF-Code, ist aber maximal (?) kurz ![]() PHP-Code: Usage Sind momentan 32 Zeichen, ich weiß, nicht ganz im Sinne der Aufgabe, aber mir war danach ![]() Greetz, inviz Geändert von Inviz (05.12.11 um 01:47 Uhr) |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Brainfuck Interpreter | CDW | Programmieraufgaben | 15 | 02.04.11 16:35 |
| Brainfuck | Easyrider | Code Kitchen | 3 | 20.10.09 23:29 |
| brainfuck - serien :) | _fux_ | Music- & Filmbox | 0 | 12.06.09 03:32 |
| assembler :(.text+0x6a): relocation truncated to fit: R_386_16 against `.text:' | <b00n> | Code Kitchen | 0 | 05.02.09 12:07 |
| Spam als Brainfuck? | non | Spiced Pork and Ham - Spam & seine Brüder | 6 | 08.05.06 21:42 |