Calcola il peso di martellamento con un peso di martellamento ridotto


19

Crea un programma che calcola il peso di martellamento di una stringa. Il vincitore è il programma con il minor peso di martellamento.

Regole:

  • Il peso di hamming per un carattere ASCII è definito come il numero totale di bit impostati su 1nella sua rappresentazione binaria.
  • Supponiamo che la codifica di input sia ASCII a 7 bit, trasmessa attraverso qualsiasi meccanismo di input normale per la tua lingua (ad es. Stdin, args, ecc.)
  • Invia il risultato, come numero, su stdout o su qualsiasi meccanismo di output predefinito / normale utilizzato dalla tua lingua.
  • Dovrebbe essere ovvio, ma devi essere in grado di eseguire effettivamente il programma, nella vita reale, affinché sia ​​una soluzione valida.
  • Winner è la soluzione il cui codice ha il minor peso di battuta.
  • Siamo spiacenti, nessuna soluzione negli spazi bianchi per questo! Ok, puoi scrivere codice negli spazi bianchi ora ho risolto le regole :)

Esempi per personaggio:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7

se prendiamo 0x20/ ASCII 32 come riferimento, non è il ronzio di hello world10 anziché di 11?
Cristian Lupascu,

Perché il peso di hello world11? Solo 10 caratteri sono diversi da uno spazio. Inoltre, il peso di un programma di Hamming sembra essere solo la sua lunghezza, esclusi gli spazi. Non così diverso dal normale golf da codice.
ugoren,

Mi dispiace, ho rovinato tutto. L'articolo di Wikipedia sul peso del martello è piuttosto fuorviante, e ho completamente fugato le regole. Riscrivendo ora. Aggiornamento: Ok, riscritto per definirlo come il numero di bit impostato su 1 nella stringa ASCII, scusate il problema.
Polinomio

@ugoren Una soluzione con caratteri ASCII di valore inferiore ha un peso di martellamento inferiore.
Polinomio

1
Ora ha tutto un senso. USO MAIUSCOLO, attenzione ~E o.
ugoren,

Risposte:



8

J, peso 34

+/,#:a.i.

Utilizzo: posiziona la stringa da misurare tra virgolette alla fine:

   +/,#:a.i.'+/,#:a.i.'
34

In alternativa, prendendo input dalla tastiera (peso 54):

   +/,#:a.i.1!:1[1
hello
21

C'è solo un modo per scrivere questo :)
effimero

Non c'è ... ho trovato una soluzione che ha un peso di martellamento inferiore.
ɐɔıʇǝɥʇuʎs,

Non cercare di essere un brivido, ma le regole richiedono un programma, non un frammento.
FUZxxl,

5

J , 39

+/,#:a.i:]

Questa è una funzione che prende un argomento. (O sostituisci ]direttamente con la stringa; come nota Gareth, questo porta il costo a 34).

   + /, #: ai:] 'ciao mondo'
45
   + /, #: ai:] '+ /, #: ai:]'
39

Grandi menti pensano allo stesso modo. :-)
Gareth

5

Python, 189

print sum(bin(ord(A)).count("1")for A in raw_input())

2
L'equivalente di Python 3 print(sum(bin(ord(A)).count('1')for A in input())), ha un punteggio di 180.
dan04

4
@ dan04: usa virgolette doppie anziché singole per 176.
Keith Randall

5

QBasic, 322 311 286 264

H$=COMMAND$
FOR A=1 TO LEN(H$)
B=ASC(MID$(H$,A,1))
WHILE B>0
D=D+B MOD 2
B=B\2
WEND
NEXT
?D

Un po ' lo strumento giusto per il lavoro, fa ancora schifo ovviamente.


1
+1 per l'utilizzo di una delle mie lingue preferite di tutti i tempi. È la prima lingua che ho imparato a programmare su un PC.
Polinomio

5

Unario 0

Sapevate tutti che stava arrivando. Innanzitutto il programma BrainFuck:

,[[>++[>>+>+<<<-]>>>
[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>
[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-]
[-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>
[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<
[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<
[>>+<[>>+>+<<<-]>>>[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>
[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]> 
[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<
[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<]>>>
[>+>+<<-]>>[<<+>>-][-]+<[>[-]<<[<<->>-]<<[>>+<<-]>>>[-]]>[<<<+<[-]>>>>
[-]]<<[->>>>+<<<<]<[-<<+>>]<<],]>>>>>>>.

Ho aggiunto nuove righe per renderlo "leggibile" ma ha un peso di Hamming di 4066. Funziona ottenendo ripetutamente il quoziente / i resti di una stringa di input e sommando tutti i resti. Ovviamente, se lo esegui su se stesso, ottieni: 226 (4066% 256) (tecnicamente \ xe2), quindi chiaramente si autodefinisce vincitore.

Ora lo convertiamo in Unario e otteniamo

000 ... 9*google^5.9 0's ... 000

Usiamo un'implementazione unaria con caratteri NULL \ x00 per '0' e boom, martellando il peso di 0.

Domanda bonus : per quali caratteri ASCII cpuoi eseguire questo programma su una stringa composta da Nripetizioni e far sì che venga emesso quel carattere. (Ad esempio una stringa di 32 spazi dà uno spazio). Quali valori di Nlavoro (o un numero infinito di essi funzionerà o nessuno funzionerà).


1
Non sono sicuro di aver capito questa soluzione. Il programma brainfuck ha un enorme peso da martellare. Unary accetta byte null come programma o è necessario implementare nuovamente Unary? Se è quest'ultimo, non è davvero una soluzione valida: chiunque potrebbe semplicemente dire "Definisco un linguaggio di programmazione in cui ogni singolo byte di input dà {risultato}" e vinci ogni sfida di golf del codice sul sito.
Polinomio

1
Un carattere null Unary andrebbe bene. Tutto ciò che serve è un EOF per dire basta conteggio. In effetti, ecco alcuni pseudo-C per leggere quel file: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }non importa affatto quale scegli di essere il tuo carattere Unario (purché non sia EOF).
Walpen

1
Bene, ecco un compilatore unario al C che funziona bene con caratteri null: ideone.com/MIvAg . Naturalmente il file richiesto per rendere questo programma non si adatterà all'universo, ma abbiamo la capacità di eseguirlo.
Walpen

3
Se non riesci effettivamente a eseguirlo, non è davvero una soluzione.
Polinomio

4
Come disse una volta Carl Sagan : "Se vuoi calcolare il peso di martellamento di una corda, devi prima inventare 10 ^ 500 universi". (miliardi e miliardi, anche)
walpen

4

C, peso 322 263 256

Il peso del martellamento conta il peso del martellamento?

main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))D+=*A%2;printf("%d",D-2);}

Utilizzate principalmente tecniche di golf standard.
Un singolo ciclo calcola il peso (spostandosi a destra e aggiungendo fino a zero) e scansiona la stringa (avanza il puntatore quando viene raggiunto lo zero).
Supponendo che Dsia inizializzato su 2 (parametro singolo).

Ottimizzazioni specifiche del peso di Hamming:
1. ABDH, con peso 2 ciascuna, utilizzate per i nomi.
2. *++Hpreferito sopra H[1].


Ah, non ho assolutamente capito la tua prima frase fino ad ora.
breadbox

Puoi ottenere il punteggio fino a 230 inviando il risultato come un numero unario :main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader

@schnaader, non ho mai saputo che @fosse una cifra nel sistema unario. Ho pensato che utilizza solo 0.. 0. Ma se vuoi andare così, printf("@"+*a%2)è più breve.
ugoren,

@ugoren: dipende dalla convenzione / definizione di unario. Ad esempio, en.wikipedia.org/wiki/Unary_numeral_system utilizza segni di conteggio e dice "Non esiste un simbolo esplicito che rappresenta lo zero in unario come lo è in altre basi tradizionali".
Schnaader,

@schnaader, OK, ma penso che stia allungando troppo il requisito "come numero".
ugoren,

4

Golfscript 84 72 58

{2base~}%{+}*

(grazie a Howard e Peter Taylor per il loro aiuto)

Input: la stringa di input deve essere nello stack (passata come argomento della riga di comando o semplicemente posizionata nello stack).

Nel caso in cui lo si esegua dalla riga di comando, assicurarsi di utilizzarlo echo -n, altrimenti verrà conteggiata anche la nuova riga finale.

Uscita: stampa il valore del peso di martellamento sulla console

Il programma può essere testato qui .


1
Golfscript fa distinzione tra maiuscole e minuscole? In caso contrario, è possibile salvare alcuni bit utilizzando BASEinvece di base. Aggiornamento: appena controllato, BASEnon funziona. Buona soluzione :)
Polynomial

@Polynomial Ho provato che dopo aver visto il tuo TEST/ testcommento :) Ma non funziona.
Cristian Lupascu,

Puoi liberarti {...}2*applicando 2base~in primo luogo. Ottiene il punteggio fino a 72.
Howard

@Ciao grazie per questo fantastico suggerimento! L'ho applicato nella mia risposta.
Cristian Lupascu,

Il tuo meccanismo di test è sbagliato, perché hai dimenticato un'importante limitazione della tua pagina Web GolfScript. Dovresti avere un carattere ;prima della stringa che sostituisci con stdin, quindi (;non è necessario. Quindi l'osservazione di Howard arriva a 65.
Peter Taylor

2

Perl, 80 (22 caratteri)

Fatto e fatto:

perl -0777nE 'say unpack"%32B*"'

Oppure ecco una versione alternativa con un peso di 77 (21 caratteri):

perl -0777pE '$_=unpack"%32B*"'

Tuttavia, questa versione non mi piace tanto, perché il suo output omette la nuova riga finale.

Per calcolare il peso, presumo che sto contando i caratteri nel solito modo (escluso il perl -e/ -E, ma includendo altri caratteri di opzione). Se per qualche motivo le persone si lamentano di questo, il meglio che posso fare senza opzioni è 90 (26 caratteri):

$/=$,,say unpack"%32B*",<>

Esempio di utilizzo:

$ perl -0777nE 'say unpack"%32b*"' rickroll.txt
7071

Boom.


2

Pyth - 15

Disclaimer: questa risposta non è idonea a vincere poiché Pyth è più giovane di questa sfida.

Utilizza .Bper la rappresentazione binaria e conta il numero di "1"'s.

/.BQ\1

Accetta input in una stringa da salvare zrispetto a Q.

Provalo online qui .


1

Scala 231

readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

Codice di autotest:

"""readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum""".map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

con modifica di autotest.


È il peso 495, non 231. Non puoi ottenere il peso 231 con 126 caratteri - che è in media meno di 2, e tutti i caratteri stampabili (tranne @e lo spazio, che non usi) hanno almeno il peso 2.
ugoren,

1
@ugoren: Ma sono solo 65 caratteri. Il programma viene stampato quasi due volte: una volta il codice per calcolare il peso di martellamento e una seconda volta come input statico per calcolarlo per il programma. Ma nella parte calcolatrice manca "readLine ()" davanti, perché prende l'input letterale. Ho cercato di chiarire la risposta stessa.
utente sconosciuto

1

Java, peso 931 774 499 454

Penso che questa sia l'unica risposta al momento con un peso superiore a circa 300.

class H{public static void main(String[]A){System.out.print(new java.math.BigInteger(A[0].getBytes()).bitCount());}}

Prevede input come argomento della riga di comando.


1

GNU sed -r, 467 + 1

(+1 per l'uso di -r- o dovrebbe essere +4?)

Output come valore unario per linea di origine; per convertire in un totale decimale, reindirizzare l'output in | tr -d "\n" | wc -c. Conta tutti i caratteri ASCII stampabili (32-126), più l'alimentazione di riga (10).

s@[a-z]@\U& @g
s@[?{}~]@      @g
s@[][/7;=>OW|^]@     @g
s@[-'+.3569:<GKMNSUVYZ\\]@    @g
s@[#%&)*,CEFIJL1248ORTX]@   @g
s@$|[!"$(ABDH0P`]@  @g
y! @!11!

È difficile evitare di elencare tutti i caratteri, ma possiamo ridurre questa osservazione osservando che le lettere minuscole hanno un peso di Hamming di una in più rispetto alle lettere maiuscole corrispondenti. Preferiamo newline (punteggio 2) rispetto al punto e virgola (punteggio 5) come separatore di istruzioni; preferiamo @(punteggio 1) o !(punteggio 2) piuttosto che /(punteggio 5) come delimitatore di pattern.

Nota: per ottenere i giusti set di caratteri, ho creato questa tabella da quella in man ascii, ordinata in base al peso. Basta aggiungere i punteggi a destra e in basso per ottenere il peso complessivo di ciascun personaggio:

   2 4   3 5 6   7 
   ---  ------   - 
0:   @   0 P `   p |0

1: ! A   1 Q a   q | 
2: " B   2 R b   r |1
4: $ D   4 T d   t | 
8: ( H   8 X h   x | 

3: # C   3 S c   s | 
5: % E   5 U e   u | 
6: & F   6 V f   v |2
9: ) I   9 Y i   y | 
A: * J   : Z j   z | 
C: , L   < \ l   | | 

7: ´ G   7 W g   w | 
B: + K   ; [ k   { |3
D: - M   = ] m   } | 
E: . N   > ^ n   ~ | 

F: / O   ? _ o     |4
   ---  ------   -  
    1      2     3

Questo potrebbe rivelarsi utile per gli altri.


0

Julia 262 268

La versione modificata utilizza la pratica funzione "count_ones" per un risparmio di 6 (262)

show(mapreduce(x->count_ones(x),+,map(x->int(x),collect(ARGS[1]))))

Versione precedente che non utilizzava la funzione di conteggio singolo integrata (268)

show(mapreduce(x->int(x)-48,+,mapreduce(x->bits(x),*,collect(ARGS[1]))))

Utilizza l'argomento della riga di comando per l'input.


0

CJam 52 o 48

Se l'input non è già nello stack (52)

q:i2fbs:s:i:+

Se l'input è nello stack (48)

:i2fbs:s:i:+

Per esempio

"Hello World":i2fbs:s:i:+

0

Julia, HW 199

H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))

Con

A="H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))"

o inserendo direttamente la stringa:

julia> H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect("H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))")))
199

La versione ungolf (HW 411) si presenta così:

bitstring=mapreduce(x->bits(x),*,collect(teststring[:]))
mapreduce(checkbit->checkbit=='1',+,bitstring)

E per divertirci, ecco una versione ottimizzata (Hamming Weight 231 ) della versione di Bakerg sul problema:

A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))

con

H="A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))"

0

HPPPL (HP Prime Programming Language), 74

sum(hamdist(ASC(a),0))

La calcolatrice grafica HP Prime ha una funzione hamdist () integrata. Il peso di martellamento di ciascun personaggio è uguale alla distanza di martellamento da 0.

ASC (stringa) crea una matrice dei valori ASCII di ciascun carattere in una stringa.

hamdist (valore, 0) calcola la distanza di hamming da 0 per ciascun valore ASCII

sum () somma tutti i valori.

Calcolo del peso di martellamento del proprio codice sorgente:

Hamming Peso HPPPL


0

05AB1E , peso 17 (4 byte )

ÇbSO

Provalo online o verifica alcuni altri casi di test .

Spiegazione:

Ç       # Convert the characters in the (implicit) input to their ASCII decimal values
        #  i.e. "Test" → [84,101,115,116]
 b      # Convert those values to binary
        #  i.e. [84,101,115,116] → ["1010100","1100101","1110011","1110100"]
  S     # Split it into a list of 0s and 1s (implicitly flattens)
        #  i.e. ["1010100","1100101","1110011","1110100"]
        #   → [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0]
   O    # Sum those (and output implicitly)
        #  i.e. [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0] → 16

0

Perl 6 , 102

+*.ords>>.base(2).comb(~1)

Provalo online!

Anche se questo non è il golf del codice, la soluzione più corta sembra avere anche il più piccolo peso martellante ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.