J: Self-di riferimento nella bolla realizzazione sorta tacita
-
04-10-2019 - |
Domanda
Dal momento che sono principiante in J ho deciso di risolvere un compito semplice utilizzando questo linguaggio, in particolare implementazione dell'algoritmo bubblesort. Io so che non è idiomaticamente per risolvere questo tipo di problema in linguaggi funzionali, perché è naturalmente risolto utilizzando una serie di elementi trasposizione in linguaggi imperativi come C, piuttosto che costruire elenco modificato in linguaggi dichiarativi. Tuttavia, questo è il codice che ho scritto:
(((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: #
Ecco la struttura della dichiarazione:
┌────────────────────────────────────────────────────────────────────────────┬──┬─┐
│┌───────────────────────────────────────────────────────────────┬──┬───────┐│^:│#│
││┌───────────────────┬─┬───────────────────────────────────────┐│^:│┌─┬─┬─┐││ │ │
│││┌──────┬─┬────────┐│,│┌──┬─┬────────────────────────────────┐││ ││1│<│#│││ │ │
││││┌──┬─┐│@│┌─┬─┬──┐││ ││$:│@│┌───────────────────┬─┬────────┐│││ │└─┴─┴─┘││ │ │
│││││<.│/││ ││2│&│{.│││ ││ │ ││┌──────┬─┬────────┐│,│┌─┬─┬──┐││││ │ ││ │ │
││││└──┴─┘│ │└─┴─┴──┘││ ││ │ │││┌──┬─┐│@│┌─┬─┬──┐││ ││2│&│}.│││││ │ ││ │ │
│││└──────┴─┴────────┘│ ││ │ ││││>.│/││ ││2│&│{.│││ │└─┴─┴──┘││││ │ ││ │ │
│││ │ ││ │ │││└──┴─┘│ │└─┴─┴──┘││ │ ││││ │ ││ │ │
│││ │ ││ │ ││└──────┴─┴────────┘│ │ ││││ │ ││ │ │
│││ │ ││ │ │└───────────────────┴─┴────────┘│││ │ ││ │ │
│││ │ │└──┴─┴────────────────────────────────┘││ │ ││ │ │
││└───────────────────┴─┴───────────────────────────────────────┘│ │ ││ │ │
│└───────────────────────────────────────────────────────────────┴──┴───────┘│ │ │
└────────────────────────────────────────────────────────────────────────────┴──┴─┘
Proviamo ad applicare ad un array:
(((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: # 5 3 8 7 2
2 3 5 7 8
La cosa che mi confonde è $:
riferendosi alla dichiarazione all'interno delle parentesi più esterne. Aiuto dice che:
$:
denota il verbo più lungo che lo contiene.
L'altro libro (~ 300 KiB) dice:
3+4
7
5*20
100
Simboli come + e * per più e volte nelle frasi di cui sopra sono chiamati verbi e rappresentano funzioni. Potresti avere più di un verbo in una frase J, nel qual caso è costruito come una frase in inglese semplice da lettura da sinistra a destra , che è mezzi
4+6%2
4
aggiunte a qualunque segue, cioè6
diviso per2
.
Riscriviamo il mio frammento di codice omettendo più esterno ()
s:
((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#) ^: # 5 3 8 7 2
2 3 5 7 8
reuslts sono gli stessi. Non riuscivo a spiegarmi il motivo per cui questo funziona, perché solo ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
viene trattato come il verbo più lunga per $:
ma non tutta la ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#) ^: #
espressione e non solo (<./@(2&{.)), $:@((>./@(2&{.)),2&}.)
, perché se ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
è un verbo, si deve anche formare un altro verbo dopo la congiunzione con #
, io. e. si potrebbe trattare l'intera frase (primo frammento) come un verbo. Probabilmente c'è qualche limite per la lunghezza, verbo limitato da una congiunzione.
Guardate il seguente codice ( da qui ):
factorial =: (* factorial@<:) ^: (1&<)
factorial 4
24
factorial
all'interno espressione si riferisce a tutta la funzione, i. e. (* factorial@<:) ^: (1&<)
.
A seguito di questo esempio ho usato un nome di funzione, invece di $:
:
bubblesort =: (((<./@(2&{.)), bubblesort@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: #
bubblesort 5 3 8 7 2
2 3 5 7 8
mi aspettavo bubblesort
fare riferimento a tutta la funzione, ma non mi sembra vero per me dal momento che il risultato è corretto.
Inoltre mi piacerebbe vedere altre implementazioni se si dispone di quelli, anche un po 'refactoring.
Grazie.
Soluzione 2
Secondo questo riferimento (175 KiB) congiunzione è:
Una parte del discorso che prende due argomenti e provoca tipicamente un verbo. Ad esempio, è un
*:^:3
funzione che itera squadratura tre volte (^:
è un assieme ).
Come ^:
cade nella suddetta categoria, applicandola ai risultati argomenti in più, verbo:
((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
A causa $:
denota il verbo più lungo che lo contiene, si riferisce al codice appena scritto sopra.
Allo stesso modo, il prossimo ^:
fa una nuova più verbo da ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
e #
:
(((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: #
, che a sua volta è a cui si riferisce $:
perché è più lunga di quella precedente.
Dal momento che è il comportamento indesiderato, l'unica soluzione consiste nel suddividere l'intero verbo modo che $:
riferisce ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
anche se non è un oneliner:
bubbleiter =: ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
bubblesort =: bubbleiter ^: #
bubblesort 3 1 2 9 2 9 86 5 9 6 9 6 45
1 2 2 3 5 6 6 9 9 9 9 45 86
Questo articolo ha alcuni commenti come a $:
:
Spiegando cosa
$:
(auto-referenza) è e come viene usato si è rivelata un punto di partenza piuttosto infelice per alcuni di quelli completamente nuovo per la lingua in quanto questo è un avanzato caratteristica ed è atipico del modo in cui le cose si realizza in J. John detto che Roger ha commentato che non sarebbe includere questo se lui sono stati la progettazione del linguaggio di oggi.
Ancora una volta, per riassumere:
-
^:
è un assieme e fa un nuovo verb dai suoi argomenti; -
$:
denota la più lunga verb che lo contiene.
Grazie a volare fuori estanford per set di dati 3 1 2 9 2 9 86 5 9 6 9 6 45
nella sua risposta.
Altri suggerimenti
sto cercando in esso. Nel frattempo, stai implementando bubblesort perché hai bisogno bubblesort specificamente, o perché avete bisogno semplicemente una specie (vale a dire che si potrebbe ottenere via con l'utilizzo di /:~
invece)?
EDIT: Hai provato in esecuzione la vostra bolla sorta su un set di dati come 3 1 2 9 2 9 86 5 9 6 9 6 45
? Il sistema si era bloccato quando l'ho provato sulla mia macchina, ma funziona se si sostituisce il finale # con un _.
Ecco un altro approccio per l'attuazione bubble sort in J: http://rosettacode.org/wiki/ Sorting_algorithms / bubble_sort # J