Domanda

Al momento sto imparando l'affascinante linguaggio di programmazione J, ma una cosa che non sono riuscito a capire è come filtrare un elenco.

Supponiamo che io ho la lista 3 2 2 7 7 2 9 arbitraria e voglio togliere le 2s ma lasciare tutto il resto invariato, vale a dire, il mio risultato sarebbe 3 7 7 9. Come diavolo faccio a fare questo?

È stato utile?

Soluzione

La risposta breve

   2 (~: # ]) 3 2 2 7 7 2 9
3 7 7 9

La risposta lunga

ho la risposta per voi, ma prima è necessario acquisire familiarità con alcuni dettagli. Qui andiamo.

Monadi, diadi

Ci sono due tipi di verbi in J: monadi e diadi . La prima accetta solo un parametro, quest'ultimo accetta due parametri.

Ad esempio il superamento di un unico argomento a un monadica verb #, chiamato tally , conta il numero di elementi nella lista:

   # 3 2 2 7 7 2 9
7

Un verbo #, che accetta due argomenti (sinistra e destra), è chiamato copiare , è diadica e viene utilizzato per copiare gli elementi dalla lista di destra come molti volte come specificato dai rispettivi elementi nella lista di sinistra (ci può essere un unico elemento nell'elenco anche):

   0 0 0 3 0 0 0 # 3 2 2 7 7 2 9
7 7 7

Forcella

C'è una nozione di forcella in J, che è una serie di 3 verbi applicata ai loro argomenti, diadicamente o monadico.

Ecco lo schema di un tipo di forcella ho usato nel primo frammento:

 x (F G H) y

      G
    /   \
   F     H
  / \   / \
 x   y x   y

Si descrive l'ordine in cui vengono applicati ai loro argomenti verbi. Così queste applicazioni si verificano:

   2 ~: 3 2 2 7 7 2 9
1 0 0 1 1 0 1

Il ~: (non uguale) è diadica in questo esempio e si traduce in un elenco di valori booleani che sono vere quando un argomento non è uguale 2. Questa è stata l'applicazione F secondo schema.

La prossima applicazione è H:

   2 ] 3 2 2 7 7 2 9
3 2 2 7 7 2 9

] ( identity ) può essere un monade o diade , ma restituisce sempre l'argomento giusto passato a un verbo (c'è un verb opposto, [ che ritorna .. Sì, l'argomento di sinistra!)

Fin qui, tutto bene. F e H dopo l'applicazione restituito questi valori di conseguenza:

1 0 0 1 1 0 1
3 2 2 7 7 2 9

L'unico passo per eseguire la G verb applicazione.

Come ho osservato in precedenza, il # verb, che è diadica (accetta due argomenti), ci permette di duplicare gli oggetti dalla all'argomento a destra il numero di volte specificato nelle rispettive posizioni nella sinistra discussione. Quindi:

   1 0 0 1 1 0 1 # 3 2 2 7 7 2 9
3 7 7 9

Abbiamo appena ricevuto l'elenco filtrato fuori 2s.

Riferimento

Leggermente diverso tipo di forcella , gancio e altri primitves (compresi quelli summenzionati) sono descritte in questi due documenti:

Altre utili fonti di informazione sono il href="http://www.jsoftware.com/" rel="noreferrer"> sito con la loro wiki e qualche mail list archivi in ??internet.

Altri suggerimenti

Giusto per essere sicuro che sia chiaro, la via diretta - per rispondere alla domanda iniziale - è questa:

   3 2 2 7 7 2 9 -. 2

Questo restituisce

3 7 7 9

Il metodo più elaborato - la generazione del valore booleano e usarlo per comprimere il vettore -. È più APLish

Per rispondere all'altra domanda nel post molto lungo, per tornare il primo elemento e il numero di volte in cui si verifica, è semplicemente questo:

      ({. , {. +/ .= ]) 1 4 1 4 2 1 3 5
1 3

Si tratta di una forcella con "{". per ottenere la prima voce, "{. + /. =]" per aggiungere il numero di volte che il primo elemento è uguale a ogni elemento, e "", come il verbo mezzo per concatenare queste due parti.

Inoltre:

   2 ( -. ~ ]) 3 2 2 7 7 2 9
3 7 7 9

Ci sono milioni di modi per fare questo - mi dà fastidio, vagamente, che queste queste cose non valutano rigorosamente da destra a sinistra, io sono un vecchio programmatore di APL e penso delle cose come destra a sinistra, anche quando non è.

Se fosse una cosa che stavo per mettere in un programma in cui ho voluto tirare fuori qualche numero e il numero è stata una costante, vorrei fare quanto segue:

(#~ 2&~:)  1 3 2 4 2 5
1 3 4 5 

Questo è un gancio genere di cose, penso. La metà destra dell'espressione genera il vettore verità riguardo che non sono 2, e poi il cancelletto sulla sinistra ha scambiato i suoi argomenti in modo che il vettore verità è l'argomento a sinistra per copiare e il vettore è l'argomento giusto. Io non sono sicuro che un gancio è più veloce o più lento di una forchetta con una copia argomento.

  +/3<+/"1(=2&{"1)/:~S:_1{;/5 6$1+i.6

156

Questa sopra programma risponde alla domanda, "Per tutte le possibili combinazioni di dadi yatzee, quanti hanno 4 o 5 numeri corrispondenti a un rotolo?" Esso genera tutte le permutazioni, in scatole, ordina ogni scatola singolarmente, li spacchettamento come effetto collaterale, e estratti colonna 2, confrontando la scatola contro la loro stessa colonna 2, nella forcella successo solo o di un gancio che abbia mai riuscito a scrivere. La teoria è che se c'è un numero che compare in un elenco di 5, tre o più volte, se si ordina l'elenco il numero centrale sarà il numero che appare con maggiore frequenza. Ho tentato una serie di altri ganci e / o forchette e ognuno ha fallito perché c'è qualcosa che proprio non capisco. In ogni caso che tabella di verità è ridotta a un vettore, e ora sappiamo esattamente quante volte ogni gruppo di 5 dadi abbinato il numero mediano. Infine, tale numero viene confrontato con 3, e il numero di successo confronto (maggiore di 3, cioè, 4 o 5) sono contati.

Questo programma risponde alla domanda, "Per tutte le possibili 8 numeri a due cifre, realizzate con i simboli da 1 a 5, con la ripetizione, quanti sono divisibili per 4?"

Lo so che è necessario solo determinare quanti entro il primo 25 è divisibile per 4 e si moltiplicano, ma il programma viene eseguito più o meno immediatamente. Ad un certo punto avevo una versione molto più complessa di questo programma che genera i numeri in base 5 in modo che le singole cifre erano tra 0 e 4, aggiunto 1 ai numeri così generato, e poi metterli nella base 10. Tale era simile 1+(8$5)#:i.5^8   + / 0 = 4 |, (8 $ 10) #. > {; / 8 5 $ 1 + I.5 78125    Finché ho solo verbo treni e la selezione, non ho un problema. Quando inizio dover ripetere la mia tesi entro il verbo in modo che io sono costretto a uso forchette e ganci comincio a perdersi.

Per esempio, ecco è qualcosa che non posso andare al lavoro.

((1&{~+/)*./\(=1&{))1 1 1 3 2 4 1

Ho sempre trovato Errore indice.

Il punto è uscita due numeri, uno che è lo stesso come il primo numero nell'elenco, il secondo che è lo stesso del numero di volte che il numero si ripete.

Quindi questo tanto opere:

*./\(=1&{)1 1 1 3 2 4 1
1 1 1 0 0 0 0

I confrontare il primo numero contro il resto della lista. Poi faccio un inserimento di un e compressione - e questo mi dà un 1 fino a quando ho una serie ininterrotta di 1 di, una volta che si rompe la e non riesce e gli zeri viene avanti

.

ho pensato che avrei potuto quindi aggiungere un altro insieme di parentesi, ottengo l'elemento di piombo dalla lista di nuovo, e in qualche modo registrare questi numeri, l'eventuale idea sarebbe quella di avere un altro stadio in cui applico l'inverso del vettore con l'originale lista, e quindi utilizzare $: per tornare per un'applicazione ricorsiva dello stesso verbo. Un po 'come l'esempio quicksort, che ho pensato che una sorta di intesa, ma credo che non lo faccio.

Ma non può nemmeno avvicinarsi. Chiederò questo come una domanda separata in modo che la gente ottiene il giusto credito per rispondere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top