NB. ===================== Beginn des J Scripts =====================

charsub=:  3 : 0
NB. characterpairs charsub data
NB. For example:
NB.    '-_$ ' charsub '$123 -456 -789'
NB.  123 _456 _789
NB. Use <rplc> for arbitrary string replacement.
:
'ft'=. ((#x.)$0 1)<@,&a./.x.
t {~ f i. y.
)

NB.  Hier werden Einzeiler definier und Namen fuer die Symbole der Stammverben
NB.  vergeben.

X  =: +/ . *                             NB. Matrizenprodukt
f  =: {:@]*{.@] { [ 
F  =: [:+/(1:,{:@])*(}:@] { [)            
g  =: {.@]                                  
TAU=: E1=: <@] C. [                NB. AusTAUschen
MUL=: E2=: f`g`[}                  NB. MULtiplizieren mit Konstante
AMU=: E3=: F`g`[}                  NB. Zeile(1) + Zeike(2)*Konstante(3)
CCO=: (<@] C. i.@{:@$@[)  {"1  [   NB. ChangeColumns of Matrix
 TAKE =: {.                        NB. Nehmen
 DROP =: }.                        NB. Loeschen  
CTAKE =: {."1                         NB. ColumnTake=Spalten nehmen
CDROP =: }."1                            NB. ColumnDrop=Spalten loeschen  
PositiveDigits=: *./@(0&<: *. <:&9)"1 # ]  NB. positive Ziffern selektieren
PAIRS  =: ,@,.        NB. Paaren= aufreihen nach annaehen  
TEXTYFY=: -.&' '@:":  NB. ohne_Leerzeichen nach deaktivieren
EXECUTE=: ".          NB. Ausfueren (eines Textes)
COUNT=: #      NB. Anzahl der Elemente im rechten Argument
COPY =: #      NB. einser in links nehmen entsprechende Elemente aus rechts
NOT  =: -.     NB. logisch nicht
NUB  =: ~.     NB. Kernmenge= keine Doppelten= nur Unikate
MATCH=: -:     NB. Test auf Identitaet
LINK =: ;      NB. Zwei Nomen verbinden => geschachtelte Liste
rowwise  =: "1 NB. Adverb: etwas zeilenweise anwenden
ANTIBASE2=: #: NB. konvertiert Dezimalzahl in Binaerzahl
TRANSPOSE=: |: NB. Zeilen mit Spalten vertauschen=Transponieren
OPEN  =: >     NB. oeffnet geschachtelte Liste zur Matrix
MAX   =: >./   NB. Maximum einer Liste
LEFT  =: [     NB. Identitaetsverb: Ergebnis ist linkes  Argument
RIGHT =: ]     NB. Identitaetsverb: Ergebnis ist rechtes Argument
INDEXOF =: i.  NB. Indizes von rechts in links
FROM=: {       NB. Index links aus Array rechts
 
NB.......................................................................
NB. SOLVE ist das Hauptprogramm, das wichtigste Verb in SOLVE ist TRY.


SOLVE=: 3 : 0
txt =: 'MONEY=SEND+MORE'
cols=:'SENDMORYGHIJ'
NB. Eingabe des Gleichungssystems als geschachtelte Liste
NB. sollte eigentlich automatisch aus txt generiert werden 
mat=: 0 0 0 1 0; 1 _1 1 0 0; 0 1 _1 0 0; 1 0 0 0 0; 0 0 0 1 _1 
mat=: mat,0 0 1 _1 0; 0 1 0 0 0; _1 0 0 0 0; _10 1 0 0 0; 0 _10 1 0 0
mat=: mat,0 0 _10 1 0; 0 0 0 _10 1
mat=: TRANSPOSE OPEN mat

NB. "haendisches" Normieren der Matrix, Gausssche Elimination
mat =: TAU&3 4 AMU&3 2 _1  AMU&3 1 _1  AMU&2 3 1 TAU&1 2 TAU&0 3 mat
mat =: CCO&5 3  TAU&3 4 MUL&4 _1 MUL&3 _1 mat
cols=:   (<5 3)C. cols        NB. Vertausche Variable 5. mit 3.

dep  =: 5 CDROP  mat          NB. abhangiger Teil des Gleichungsystems
indep=: 5 CTAKE  mat          NB. Unabhaengiger Teil des Gleichungsystems(5x5)
TRY  =: %.&indep@:(-@(dep&X)) NB. Verb TRY setzt abhaengige Variablen ein und
                              NB. rechnet die unabhaengigen () aus
                              NB. %. ist der Gleichungsloeser
all2p4=: ANTIBASE2 i. 2^4     NB. ghij: all arrangements of 0 1 in groups of 4 
                              NB. #: uebersetzt 0 1 2 ... 14 15 ins Binaersystem
all2  =: ,/ ,"0/~ i.10        NB.  RY: alle Ziffern-Arrangements in 2-er Gruppen
all3  =: ,/ all2 ,"1 0/ i.10  NB. DRY: alle Ziffern-Arrangements in 2-er Gruppen
all   =: ,/ all3 ,"1/ all2p4  NB. alle 1600 Kombiantionen der abhaengigen Variablen
                              NB. Das Wichtigste kommt jetzt!!! 
res=: TRY"1  all              NB. Einsetzen und unabhaengige Vars. bestimmen
                              NB. 1600x5 Matrix mit allen Loesungen fuer die unabhaengigen

NB. Jetzt werden die Zeilen die nur positive Ziffern enthalten selektiert
NB. Als Ergebnis erhaelt man alle Kombinationen fuer alle acht Buchstaben 
res0 =: PositiveDigits res ,. 3{."1 all

res  =: TEXTYFY"1 res0       NB. Zahlen in Texte ohne Leerzeichen umwandeln
chars=: _4 DROP cols         NB. ohne Hilsvariablen GHIJ
res  =: chars PAIRS"1 res    NB. Buchstaben-Zahlen-Paare fuer's austauschen
res  =: res charsub"1 txt    NB. Ersetzen der Buchstaben durch Zahlen

boo=.(COUNT@NUB MATCH COUNT)rowwise res0
uniques=.boo COPY res        NB. Loesungen ohne doppelte Ziffern
doubles=.((NOT boo)COPY res) NB. Loesungen mit doppelten Ziffern

NB. selektiert groesste Loesung aus Matrix mit den Loesungen in den Zeilen
MAXIMUM=. (RIGHT INDEXOF MAX)@:EXECUTE@(5&CTAKE) FROM RIGHT

result=. uniques ( LEFT ; RIGHT ; MAXIMUM@LEFT ,: MAXIMUM@RIGHT) doubles   
NB. Das Ergebnis ist eine geschachtelte Liste mit 3 Schachteln
NB. 1.) Loesungen ohne doppelte Ziffern
NB. 2.) Loesungen mit doppelten Ziffern
NB. 3.) die maximalen Loesungen aus 1.) und 2.)
)

NB.............................................................................
NB. Aufruf des Verbs SOLVE mit leerem Argument

result=: SOLVE''

NB. The End

