Digitale Härte von ganzen Zahlen

26

So finden Sie die digitale Härte einer ganzen Zahl, nehmen seine binäre Darstellung und zählen die Anzahl der Zeiten sowohl eine führende und nachlauf 1kann entfernt werden , bis sie entweder mit einem Start oder Enden 0. Die Gesamtzahl der entfernten Bits ist die digitale Härte.

Das ist eine ziemlich wortreiche Erklärung - also lasst es uns mit einem ausgearbeiteten Beispiel aufschlüsseln.

In diesem Beispiel verwenden wir die Nummer 3167. In der Binärdatei ist dies:

110001011111

(Beachten Sie, dass Sie bei der Konvertierung in eine Binärdatei sicherstellen sollten, dass führende Nullen entfernt werden.)

Es beginnt oder endet nicht mit 0, also entfernen wir 1 Paar Bits:

1  1000101111  1

Und ein anderer:

11  00010111  11

Aber jetzt gibt es eine 0 am Anfang, so dass wir keine 1Paare mehr entfernen können . Insgesamt haben wir 4 Bits entfernt, also 4 die digitale Härte von 3167.

Für Zahlen, die als 2 n -1 für positives n geschrieben werden können (dh nur enthalten)1 in binärer Darstellung enthalten), wird 0 jedoch niemals erreicht, und so können alle Bits entfernt werden. Dies bedeutet, dass die Härte einfach die Bitlänge der ganzen Zahl ist.


Die Herausforderung

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die eine nicht negative ganze Zahl enthält n >= 0 die digitale Härte bestimmt.

Sie können ein vollständiges Programm einreichen, das E / A ausführt, oder eine Funktion, die das Ergebnis zurückgibt. Ihre Eingabe sollte für Werte von "" funktionierenn innerhalb des ganzzahligen Standardbereichs Ihrer Sprache .


Testfälle

Bitte benachrichtigen Sie mich, wenn eine dieser Angaben nicht korrekt ist oder wenn Sie Randfälle vorschlagen möchten, die hinzugefügt werden sollen.

0     -> 0
1     -> 1
8     -> 0
23    -> 2
31    -> 5
103   -> 4
127   -> 7
1877  -> 2
2015  -> 10

Hier ist die ungolfed Python-Lösung, mit der ich diese Testfälle generiert habe (ohne Gewähr, dass sie fehlerfrei sind):

def hardness(num) -> int:
    binary = bin(num)[2:]

    if binary.count('0') == 0:
        return num.bit_length()

    revbin = binary[::-1]

    return min(revbin.find('0'), binary.find('0')) * 2
FlipTack
quelle
1
Wie wird 11 zurückgegeben, wenn überhaupt nichts enthalten ist 0? Ich meine, Sie können unmöglich genug Einsen aus der Zeichenkette entfernen, um den Anfang oder das Ende zu haben 0.
busukxuan
2
@busukxuan Lesen Sie den Absatz kurz vor der Überschrift "Die Herausforderung": Bei Zahlen, die als 2 ^ n-1 geschrieben werden können (dh nur 1 in binärer Darstellung enthalten), wird 0 niemals erreicht, und daher können alle Bits entfernt werden . Dies bedeutet, dass die Härte einfach die Bitlänge der ganzen Zahl ist.
FlipTack
2
@busukxuan Sie können sich das als die Anzahl der Einsen vorstellen, mit denen jede Seite aufgefüllt ist, bevor Nullen erreicht werden.
FlipTack
2
An den Abwähler, der die Kantenfälle offensichtlich nicht mochte: Die Härte ist die Anzahl der festen (1) Bits, mit denen es gepolstert ist - wenn das Ganze fest ist, dann hat es sicherlich 100% Härte, seine gesamte Bitlänge?
FlipTack
1
@FlipTack Ich möchte nicht zu viel beeinflussen, es ist deine Herausforderung. Ich verstand anfangs "Härte" als die maximale Anzahl von äußeren Paaren , die entfernt werden können, eines von jeder Seite. Aber Sie können Recht haben, wenn eine einzige am Ende bleibt, sollte sie vielleicht mitgezählt werden
Luis Mendo

Antworten:

6

Gelee , 11 bis 10 Bytes

BµQL××Ṛa\S

Probieren Sie es online!

Wie es funktioniert

BµQL××Ṛa\S  Main link. Argument: n

B           Binary; convert n to base 2.
 µ          Begin a new, monadic chain. Argument: A (array of binary digits)
  Q         Unique; deduplicate the digits.
   L        Length; count the unique digits.
    ×       Multiply each digit by the result.
     ×Ṛ     Multiply the results by reversed A.
       a\   Cumulative reduce by logical AND.
            This zeroes out all elements after the first zero.
         S  Compute the sum of the result.
Dennis
quelle
8

Python , 76 69 68 63 62 60 57 Bytes

f=lambda n,k=0:n>>k&(n&n>>k>n>>k+1)and(n&n+1>0)-~f(n,k+1)

Probieren Sie es online!

Wie es funktioniert

Dies ist eine rekursive Lösung, die eine Eingabe n annimmt und k - beginnend bei 0 - weiter inkrementiert, während sowohl das LSB k (n) (Bit bei Index k von rechts) als auch das MSB k (n) (Bit bei Index k von links) eingestellt sind. Sobald dies beendet ist, wird k zurückgegeben, wenn alle Bits von n gesetzt sind und 2k sind wenn dies nicht der ist.

Beginnen wir damit, das Lambda f als benannte Funktion F mit einer Hilfsvariablen t umzuschreiben .

def F(n, k = 0):
    t = n >> k
    return t & (n & t > t >> 1) and (n & (n + 1) > 0) + 1 + F(n, k + 1)

Bei jedem Aufruf von F verschieben wir zuerst n insgesamt k bitweise Einheiten nach rechts bitverschoben und das Ergebnis in t gespeichert . Auf diese Weise ist LSB 0 (t) = LSB k (n) , so dass t genau dann ungerade ist, wenn LSB k (n) gesetzt ist.

Bestimmen, ob MSB k (n) gesetzt ist, ist etwas schwieriger; das ist es, wasn & t > t >> 1erreicht wird. Betrachten wir zur Veranschaulichung der Funktionsweiseeine ganze Zahl n = 1αβγδεζη 2 mit der Bitlänge 8 und analysieren Sie den Funktionsaufruf F (n, 3) , dh k = 3 .

Wir versuchen festzustellen, ob MSB 3 (n) = γ gesetzt ist, indem den Wahrheitswert des Vergleichs untersuchen (n & t> t >> 1) = (1αβγδεζη 2 & 1αβγδ 2 > 1αβγ 2 ) . Untersuchen wir die beteiligten ganzen Zahlen.

MSB-index  012k4567

n          1αβγδεζη
t             1αβγδ

t >> 1         1αβγ

Wir behaupten, dass genau dann γ = 1 ist, wenn n & t> t >> 1 ist .

  • Ob γ = 1 ist , hat n & t die Bitlänge 5, während t >> 1 die Bitlänge 4 hat , also ist n & t> t >> 1 .

    Dies beweist, dass γ = 1 n & t> t >> 1 impliziert .

  • Wenn n & t> t >> 1 ist , gibt es zwei Möglichkeiten: entweder γ = 1 oder γ = 0 . Im ersten Fall gibt es nichts mehr zu beweisen.

    Im zweiten Fall gilt αβγδ 2 ≥ n & t> t >> 1 = 1αβγ 2 .

    Da αβγδ 2 > 1αβγ 2 ist , müssen wir MSB 0 (αβγδ 2 haben ) ≥ MSB 0 (1αβγ 2 ) haben , was bedeutet, dass α = 1 ist .

    Auf diese Weise ist 1βγδ 2 > 11βγ 2 , also müssen wir MSB 1 haben (1βγδ 2 ) ≥ MSB 1 (11βγ 2 ) haben , was bedeutet, dass β = 1 ist .

    Dies impliziert wiederum, dass 11γδ 2 > 111γ 2 ist . Wenn wir uns daran erinnern, dass im zweiten Fall γ = 0 ist, erhalten wir die Ungleichung 110δ 2 > 1110 2 , die falsch ist, da MSB 2 (110δ 2 ) = 0 <1 = MSB 2 (1110 2 ) .

    Somit ist nur der erste Fall möglich und n & t> t >> 1 impliziert γ = 1 .

Zusammenfassend ist, wenn sowohl LSB k (n) als auch MSB k (n) gesetzt sind, t ungerade und n & t> t >> 1 ist wahr , so dass t & (n & t> t >> 1) ist Ausbeute 1 . Wenn jedoch LSB k (n) oder MSB k (n) nicht gesetzt ist (oder wenn beide gesetzt sind), wird t gerade sein oder n & t> t >> 1 wird falsch sein , so dass t & (n & t> t> > 1) ergibt 0 .

Wenn Sie F mit einem einzelnen Argument aufrufen, wird k = 0 initialisiert . Während die oben beschriebene Bedingung zutrifft, wird der Code after andausgeführt, der (unter anderem) rekursiv F mit inkrementiertem k aufruft .

Sobald LSB k (n) oder MSB k (n) nicht gesetzt ist, schlägt die Bedingung fehl und F (n, k) gibt 0 zurück . Jeder der vorhergehenden k Funktionsaufrufe addiert (n & (n + 1)> 0) + 1 zu F (n, k) = 0 , so dass F (n) ((n & (n + 1)> 0) + zurückgibt 1) k .

Wenn nun alle Bits von n gleich sind (dh wenn n entweder 0 ist oder alle seine Bits gesetzt sind), hat n + 1 keine Bits gemeinsam mit n , so dass n & (n + 1) = 0 und F (n) gibt k zurück . Wenn jedoch n beide Satz und ungesetzt Bits, n & amp ; (n + 1)> 0 und F (n) liefert 2k .

Dennis
quelle
2
Rekursive Lösungen in Python scheinen in letzter Zeit sehr gut abzuschneiden.
mbomb007
Zumindest im Vergleich zu iterativen Lösungen haben sie es immer getan. input(), whileUnd printsind bereits 17 Bytes ...
Dennis
Ja, aber ich finde es viel schwieriger, sie zu schreiben.
mbomb007
1
Meinetwegen. Eine einfache iterative Implementierung derselben Idee wäre jedoch nur 5 Byte länger. tio.run/nexus/… 2 weitere Bytes könnten mit ein paar Tricks gespeichert werden. tio.run/nexus/python2#JY1BDsIgFAXX7SnepgUUI1BNm1K4jKVJQ/…
Dennis
6

MATL , 13 - 12 Bytes

Btv`6L&)}x@q

Probieren Sie es online!Oder überprüfen Sie alle Testfälle .

Erläuterung

Der Code wiederholt jede Binärziffer und zählt, wie oft es möglich ist, zwei äußere zu entfernen.

B        % Input number (implicit). Horizontal vector of binary digits
tv       % Duplicate and concatenate vertically
`        % Do...while
  6L&)   %   Flatten the array if needed (in column-major order), and split it
         %   into two subarrays: one with the inner entries, and another
         %   with the two outer entries. The latter will be used for deciding
         %   if the loop continues or is exited
}        % Finally (execute before exiting the loop)
  x      %   Delete last subarray of inner entries
  @q     %   Push last iteration index minus 1
         % End (implicit). The next iterarion is executed if the array at the
         % top of the stack is non-empty and only contains nonzero values. 
         % Otherwise the loop is exited, executing the "finally" block first
         % Display (implicit)
Luis Mendo
quelle
6

Python, 82 Bytes

Ich habe das Gefühl, es kann immer noch Golf gespielt werden, aber ich habe eine Weile damit verbracht, verschiedene Methoden auszuprobieren, und dies war die kürzeste.

def f(n):b=bin(n)[2:];x=min(b.find('0'),b[::-1].find('0'));print(x<0)*len(b)or x*2

Probieren Sie es online aus

Obwohl dies ähnlich wie das Python-Programm des OP funktioniert, habe ich dies vor dem Posten der Frage erstellt, nachdem ich die Frage in der Sandbox angezeigt hatte, die kein solches Programm enthielt.

mbomb007
quelle
6

Python 2, 66 Bytes

s=bin(input())[2:].split('0')
print len(min(s[-1],s[0]))<<1%len(s)

Teilt die binäre Darstellung der Eingabe in Blöcke von 1 auf. Zählt die Anzahl der Einsen im kleineren des ersten und letzten Blocks und verdoppelt sie dann, es sei denn, es gibt einen einzelnen Block, der doppelt gezählt wird.

xnor
quelle
Clever, aber dennoch leicht verständlich. Ich mag das!
mbomb007
5
@ Mbomb007 Nehmen Sie es als Aufwärmen für das Verständnis von Dennis :)
Xnor
3

PowerShell , 109 106 Bytes

$a=[convert]::ToString($args[0],2)-split0;(((($b=$a[0].length),$a[-1].length|sort)[0]*2),$b)[$a.count-eq1]

Probieren Sie es online!

Nimmt die Eingabe $args[0], verwendet den .NET Aufruf convertes toStringmit Base 2(dh es binär), dann -splitS, die Zeichenfolge auf 0s, speichert , die in $a. Wichtig zu beachten: Der .NET-Aufruf gibt keine führenden Nullen zurück, daher ist die erste Ziffer immer ein1 .

Es gibt also zwei Möglichkeiten - die Binärzeichenfolge ist alle Eins, oder es gab mindestens eine Null. Wir unterscheiden zwischen jenen mit einem pseudoternären Index von $a.count-eq1. Wenn die Binärdatei mindestens eine Null hat, nehmen wir im linken Fall das Minimum der Länge der ersten [0]Zeichenfolge von1 s und der letzten [-1]Zeichenfolge (gefunden von |sortund dann [0]). Je kürzer das ist, desto mehr Paare können wir entfernen, also multiplizieren wir das mit 2. Beachten Sie, dass , wenn die ursprünglichen Binärkette Enden in eine 0, wie für die Eingabe 8, die dann [-1].lengthwird auch 0(da es sich um eine leere Zeichenfolge ist), die , wenn sie multipliziert mit 2noch ist0 .

Andernfalls nehmen wir bei allen binären Zeichenfolgen nur $b(die zuvor als Länge der ersten festgelegt wurde)[0] Zeichenfolge festgelegt wurde, in diesem Fall die Gesamtheit der Binärzeichenfolge).

In beiden Situationen verbleibt dieses Ergebnis in der Pipeline und die Ausgabe ist implizit.

AdmBorkBork
quelle
3

JavaScript (ES6), 57 Byte

f=
n=>n.toString(2).replace(/^(1*)(.*(\1))?$/,'$1$3').length
<input oninput=o.value=1/this.value?f(+this.value):''><input id=o readonly>

Nimmt die Binärdatei und versucht, alle 1soder fehlgeschlagene Werte mit der gleichen Anzahl von führenden und nachfolgenden zu vergleichen 1s.

Neil
quelle
2

Netzhaut , 48 Bytes

.+
$*
+`(1+)\1
$1o
o1
1
m(+`^1(.*)1$
xx¶$1
x|^1$

Probieren Sie es online aus

Erläuterung:

.+              # Convert to unary
$*
+`(1+)\1        # Convert to binary (but with `o` instead of `0` -- it's shorter)
$1o
o1
1
m(+`^1(.*)1$    # Replace pairs of surrounding ones with `xx`
xx¶$1
x|^1$,          # Count x's, including the possibility of a single remaining `1`
mbomb007
quelle
2

133 Bytes

Funktion, die die Härte zurückgibt. Übernimmt eine Ganzzahl aus dem Argument.

int h(int b){var n=Convert.ToString(b,2);for(b=0;;){if(n[0]+n[n.Length-1]==98)n=n.Substring(1,n.Length-2);else break;b+=2;}return b;}

Nun, heute habe ich es '1' + '1' = 98in C # herausgefunden.

devRicher
quelle
1
Das '1'liegt daran, dass das ASCII-Zeichen 49 und 49 + 49 = 98 ist.
FlipTack
Ich habe buchstäblich 10 Minuten damit verbracht herauszufinden, warum meine 1 + 1 = 2nicht funktioniert hat. @FlipTack
devRicher
2

C 89 88 85 Bytes

Zwei Bytes gespart, weil @FlipTack auf eine nutzlose Deklaration hinwies.

f()Mit der zu testenden Nummer anrufen , die Ausgabe wird von der Funktion zurückgegeben.

t,h;f(l){for(t=l;t&&~t&1<<30;t*=2);for(h=0;t&1<<30&&l&1;t*=2,l/=2)++h;return h<<!!l;}

Probiere es auf ideone aus .

owacoder
quelle
2

JavaScript (ES6), 59-58 Byte

f=(n,m=1<<30)=>m>n?f(n,m/2):m>1?n&m&&n&1&&2+f(n/2,m/4):n&1

Testfälle

Arnauld
quelle
2

C, 137 132 122 119 117 114 98 94 92 87 85 Bytes

Zeit zum Golfen B-)

i,j;f(n){for(i=1<<30;i&~n;i/=2);for(j=0;n&i;n/=2,i/=4)j+=~n&1?i=0:2;return j-=n<1*j;}

Hier ist der Beweis

main()
{
  printf("%d %d\n", 0, f(0));
  printf("%d %d\n", 1, f(1));
  printf("%d %d\n", 8, f(8));
  printf("%d %d\n", 23, f(23));
  printf("%d %d\n", 31, f(31));
  printf("%d %d\n", 103, f(103));
  printf("%d %d\n", 127, f(127));
  printf("%d %d\n", 1877, f(1877));
  printf("%d %d\n", 2015, f(2015));
  printf("%d %d\n", 3167, f(3167));
} 

und die Ausgabe;

0 0
1 1
8 0
23 2
31 5
103 4
127 7
1877 2
2015 10
3167 4 
Cleblanc
quelle
1

Java (OpenJDK) , 181 156 150 Bytes

n->{int i=0;String s=n.toString(n,2);if(s.matches("1*"))i=s.length();else for(;!s.matches("(.*0)|(0.*)");s=s.substring(1,s.length()-1))i+=2;return i;}

Probieren Sie es online!

Pavel
quelle
1

Mathematica, 63 56 Bytes

(2-Min[l=#~IntegerDigits~2])Min[Tr/@Split[l][[{1,-1}]]]&

Erläuterung

l=#~IntegerDigits~2

Generieren Sie die Basis-2-Darstellung der Eingabe, umschlossen mit einem List . Bewahren Sie das inl

(2-Min[...])

Wenn das Element min von l 1 ist, geben Sie 1 aus. Wenn nicht, geben Sie 2 aus. Multiplizieren Sie dies mit ...

Split[l]

Teilt l in Läufe.

... [[{1,-1}]]

Nimm das erste und das letzte Element.

Tr/@ ...

Nehmen Sie die Summe von beiden.

Min[ ... ]

Finde den kleineren zwischen den beiden.

(Multiplizieren Sie das erste Ergebnis (1 oder 2) mit diesem Ergebnis).

JungHwan min
quelle
1

Oktave, 56 54 Bytes

 @(n)cummin(d=dec2bin(n)-48)*cummin(flip(d))'*2^!all(d)

Probieren Sie es online!

Erläuterung:

d=dec2bin(n)-48

binäre Darstellung von n

cumd= cummin(d);
cumfd = cummin(flip(d));

Nehmen Sie kumulative min von d und kumulative min von flippedd

res = cumd * cumfd ';

Matrixmultiplikation durchführen

out = res*2^!all(d)

mit 2 multiplizieren, wenn alle Ziffern 1 sind;

rahnema1
quelle
@FlipTack Danke, Link aktualisiert!
rahnema1
1

Pyth, 18 Bytes

?*FJjQ2lJyhSxR0_BJ

Ein Programm, das die Eingabe einer Ganzzahl akzeptiert und das Ergebnis ausgibt.

Testsuite (Erste Zeile zur Formatierung)

Wie es funktioniert

?*FJjQ2lJyhSxR0_BJ  Program. Input: Q
?                   If
  F                 reducing
    jQ2             the binary representation of Q as a list
   J                (store in J)
 *                  by multiplication is truthy:
       lJ            Yield len(J)
                    Else:
          hS         Yield the minimum
            xR0      of the first index of zero
               _BJ   in J and its reverse
         y           * 2
                    Implicitly print
TheBikingViking
quelle
1

APL, 26 Bytes

+/∘(∧\≢↑(∊⊢(,∧∧)¨⌽))2⊥⍣¯1⊢

Testfälle:

      ( +/∘(∧\≢↑(∊⊢(,∧∧)¨⌽))2⊥⍣¯1⊢ ) ¨ 0 1 8 23 31 103 127 1877 2015    
0 1 0 2 5 4 7 2 10

Erläuterung:

+ / ∘ (∧ \ ≢ ↑ (∊⊢ (, ∧∧) ¨⌽)) 2⊥⍣¯1⊢

                         ⊢ Eingabe
                    2⊥⍣¯1 in binäre Darstellung konvertieren
   ()
        (⊢ ¨⌽) für jedes Bit und sein passendes Bit auf der anderen Seite
            (∧) nimm das logische und von beiden Bits,
             , mache eine Liste von beiden Bits,
              ∧ Nehmen Sie dann das und der Liste und das und
         ∊ Reduzieren Sie das resultierende Array
      ≢ ↑ nimm nur die ersten N Bits, wobei N das ist
                                Länge der ursprünglichen Bitliste
    Nimm ein laufendes logisches und (lass nur das
                                Starter)
+ / ∘ summieren diese
Marinus
quelle
1

J, 22 Bytes

(#<.2*(<.&(#.~)|.))@#:

Dies basiert auf dem tollen Trick, der aus dieser Herausforderung gelernt wurde .

Probieren Sie es online!

Erläuterung

(#<.2*(<.&(#.~)|.))@#:  Input: integer n
                    #:  Binary digits of n
(                 )@    Operate on those digits D
               |.         Reverse D
       <.                 Take the minimum of
         &(#.~)           the "trailing truths" of D and reverse(D)
    2*                    Multiply by 2
 #                        The length of D
  <.                      Minimum of length and the previous result
Meilen
quelle
1

PHP, 83 74 Bytes

3 + 6 Bytes gespeichert von Jörg

<?=(~$s=decbin($argn))[$a=strspn($s,1)]?min($a,strspn(strrev($s),1))*2:$a;

nimmt Eingaben von STDIN entgegen; renn mit -nR.

Nervenzusammenbruch

<?=                     # print ...
(~
    $s=decbin($argn)        # $s = binary representation of input
)[
    $a=strspn($s,1)         # $a = number of leading `1`s
]                           # if $s has more than $a digits,
?   min($a,                     # 2. minimum of $a and
        strspn(strrev($s),1)    # 1. number of trailing `1`s
    )*2                         # 3. *2
:   $a                      # else $a (==strlen)
Titus
quelle
1
<?=~($s=decbin($argn))[$a=strspn($s,1)]?2*min($a,strspn(strrev($s),1)):$a;
Jörg Hülsermann
0

JavaScript (ES6), 83 Bytes

f=x=>(y=x.toString(2),y.match(/^1*$/)?y:([s,e]=y.match(/^1*|1*$/g),s<e?s:e)).length

Ungolfed:

function f(n) {
    var binStr = n.toString(2);
    if(binStr.match(/^1*$/)) {
        // If binary representation is all 1s, return length of binary
        return binStr.length;
    } else {
        // Grab the starting and ending 1s in the binary representation
        var [start1s, end1s] = binStr.match(/^1*|1*$/g);
        var startHardness = start1s.length;
        var endHardness = end1s.length;
        return Math.min(startHardness, endHardness);
    }
}
Joshua David
quelle
0

Mathematica, 62 Bytes

(h=0;#~IntegerDigits~2//.{{1,m___,1}:>(h+=2;{m}),{1}:>h++};h)&

Reine Funktion, wobei #das erste Argument darstellt.

(h=0;...;h)&setzt h=0, macht ein paar Sachen ..., gibt dann zurück h(die Härte). Schauen wir uns die ganzen Sachen an:

#~IntegerDigits~2                                     Binary representation of the input
                 //.                                  Apply the following list of rules repeatedly until there is no change
                    {                                 Start of the list of rules
                     {1,m___,1}                       If you see a list starting and ending with 1 with the sequence m (possibly empty) in between
                               :>(h+=2;{m}),            replace it with just {m} after incrementing h twice.
                                            {1}       If you see the singleton list {1}
                                               :>h++    replace it with h, then increment h.
                                                    } End of the list of rules

Vielen Dank an Greg Martin für die Einführung in diesen Trick .

Genisis
quelle
0

Haskell , 94-92 Bytes

b 0=[]
b n=mod n 2:b(div n 2)
h n|(c,_:_)<-span(>0)$zipWith(*)n$reverse n=c++c|1<3=n
sum.h.b

Probieren Sie es online! Verwendung:

Prelude> sum.h.b $ 3167
4

Erläuterung:
b Konvertiert eine Zahl in eine Binärzahl und gibt eine Liste mit Nullen und Einsen mit dem niedrigstwertigen Bit zuerst zurück. In hwird diese Liste umgekehrt und elementweise mit der ursprünglichen Liste multipliziert und dann span(>0)nach dem Anfangsbuchstaben 1s aufgeteilt:

       b 3167 = [1,1,1,1,1,0,1,0,0,0,1,1] = n
    reverse n = [1,1,0,0,0,1,0,1,1,1,1,1] = m
zipWith(*)n m = [1,1,0,0,0,0,0,0,0,0,1,1] = z
   span(>0) z = ([1,1],[0,0,0,0,0,0,0,0,1,1])

Das resultierende Tupel wird mit (c,_:_)dem Muster abgeglichen, mit dem _:_eine nicht leere Liste übereinstimmt c = [1,1]. Da die Bytes vorne und hinten entfernt werden, c++c = [1,1,1,1]werden sie zurückgegeben und schließlich summiert, um die digitale Härte zu erhalten .

Wenn die zweite Liste des Tupels leer ist, enthält die Binärdarstellung nur Einsen, und die Anzahl der Einsen ist die digitale Härte. Mit dem Mustervergleich fehlgeschlagenh eben das zurückgegeben n, was nochmal aufsummiert wird.

Laikoni
quelle
0

Perl, 61 Bytes

sub f{$_=sprintf('%b',pop);length(/0/?/^(1+).*\1$/&&$1x2:$_)}

Das Herzstück ist der reguläre Ausdruck, /^(1+).*\1$/bei dem das Zweifache der Länge $1die Antwort ist. Der Rest des Codes ist Overhead und beschäftigt sich mit dem Spezialfall all 1.

cdlane
quelle
Sie können die Klammer um sprintfArgumente weglassen . Außerdem können Sie mit -pflag ein vollständiges Programm schreiben, das kürzer ist als Ihre Funktion, da Sie es weglassen können sub f{...}(stattdessen müssen Sie mit enden, $_=...aber das ist immer noch eine Verbesserung um 4 Byte). Schließlich können Sie anstelle von Ihrem length(...)tun /0/&&s/^(1+).*\1$/$1$1/;$_=y///c. Dies sollte Sie auf 51 Bytes bringen.
Dada
0

PHP, 65 Bytes

<?=strlen(preg_filter('#^(1*)(.*(\1))?$#',"$1$3",decbin($argn)));

Online Version

Jörg Hülsermann
quelle
0

CJam, 14 Bytes

ri2b_0#\W%0#e<

Erläuterung:

ri e# Read integer:      | 3167
2b e# Convert to binary: | [1 1 0 0 0 1 0 1 1 1 1 1]
_  e# Duplicate:         | [1 1 0 0 0 1 0 1 1 1 1 1] [1 1 0 0 0 1 0 1 1 1 1 1]
0# e# Index of first 0:  | [1 1 0 0 0 1 0 1 1 1 1 1] 2
\  e# Swap:              | 2 [1 1 0 0 0 1 0 1 1 1 1 1]
W% e# Reverse:           | 2 [1 1 1 1 1 0 1 0 0 0 1 1]
0# e# Index of first 0:  | 2 5
e< e# Minimum:           | 2
Esolanging Fruit
quelle