(KevinC's) Dreieckige DeziDigits-Sequenz


19

Eingang:

Eine positive ganze Zahl n ist 1 <= n <= 25000.

Ausgabe:

  1. In dieser Reihenfolge beginnen wir mit der Dezimalzahl 1 / n .
  2. Dann nehmen wir die Summe der Ziffern bis zur n -ten Stelle nach dem Komma (1-indiziert); gefolgt von der Summe der Ziffern bis zum ( n- 1) -ten, dann ( n-2 ) -ten usw. Fahren Sie fort, bis n 1 ist.
  3. Die Ausgabe ist die Summe aller dieser Werte.

Beispielsweise:

n = 7
1/7 = 0.1428571428...
7th digit-sum = 1+4+2+8+5+7+1 = 28
6th digit-sum = 1+4+2+8+5+7 = 27
5th digit-sum = 1+4+2+8+5 = 20
4th digit-sum = 1+4+2+8 = 15
3rd digit-sum = 1+4+2 = 7
2nd digit-sum = 1+4 = 5
1st digit     = 1
Output = 28+27+20+15+7+5+1 = 103

Herausforderungsregeln:

  • Wenn die Dezimalstelle von 1 / n keine n Stellen nach dem Komma enthält, werden die fehlenden als 0 (dh 1/2 = 0.50 => (5+0) + (5) = 10) gezählt.
  • Sie nehmen die Ziffern ohne Rundung (dh die Ziffern von 1/6sind 166666und nicht 166667)

Allgemeine Regeln:

  • Für Ihre Antwort gelten Standardregeln. Daher dürfen Sie STDIN / STDOUT, Funktionen / Methode mit den richtigen Parametern und vollständige Programme verwenden. Ihr Anruf.
  • Standardlücken sind verboten.
  • Fügen Sie nach Möglichkeit einen Link mit einem Test für Ihren Code hinzu.
  • Fügen Sie ggf. auch eine Erklärung hinzu.

Erste 1 - 50 in der Sequenz:

0, 10, 18, 23, 10, 96, 103, 52, 45, 10, 270, 253, 402, 403, 630, 183, 660, 765, 819, 95, 975, 1034, 1221, 1500, 96, 1479, 1197, 1658, 1953, 1305, 1674, 321, 816, 2490, 2704, 4235, 2022, 3242, 2295, 268, 2944, 3787, 3874, 4097, 1980, 4380, 4968, 3424, 4854, 98

Letzte 24990 - 25000 in der Reihenfolge:

1405098782, 1417995426, 1364392256, 1404501980, 1408005544, 1377273489, 1395684561, 1405849947, 1406216741, 1142066735, 99984

8
Hat jemand meinen Namen erwähnt?
Kevin

Antworten:



15

Mathematica, 42 Bytes

#&@@RealDigits[1/#,10,#,-1].(#-Range@#+1)&

oder

#&@@RealDigits[1/#,10,#,-1].Range[#,1,-1]&

oder

Tr@Accumulate@#&@@RealDigits[1/#,10,#,-1]&

Erläuterung

Nehmen Sie das Beispiel aus der Herausforderungsspezifikation. Wir wollen berechnen:

  1+4+2+8+5+7+1
+ 1+4+2+8+5+7
+ 1+4+2+8+5
+ 1+4+2+8
+ 1+4+2
+ 1+4
+ 1

Neu anordnen, das ist:

  1*7 + 4*6 + 2*5 + 8*4 + 5*3 + 7*2 + 1*1
= (1, 4, 2, 8, 5, 7, 1) . (7, 6, 5, 4, 3, 2, 1)

wo .ist das Skalarprodukt von zwei Vektoren.

Das ist so ziemlich die ganze Lösung.

#&@@RealDigits[1/#,10,#,-1]

Dadurch erhalten wir die ersten NDezimalstellen von 1/N(der #&@@extrahiert das erste Element des RealDigitsErgebnisses, da dies auch den Versatz der ersten Stelle zurückgibt, der uns egal ist).

Dann erhalten wir die Liste von Nunten bis 1entweder mit (#-Range@#+1)oder Range[#,1,-1], die beide kürzer als sind Reverse@Range@#, und nehmen das Skalarprodukt.

Die alternative Lösung Accumulateberechnet stattdessen eine Liste aller Präfixsummen und addiert diese Präfixsummen mit Tr.

Da dies auch für große Eingaben sehr schnell ist, finden Sie hier eine Streudiagramm der Sequenz bis zu N = 100,000(es dauerte jedoch eine Weile , bis alle erstellt und geplottet wurden):

Bildbeschreibung hier eingeben
Klicken Sie für eine größere Version.

Die blaue Linie ist die naive Obergrenze von 9 N (N+1) / 2(wenn alle Dezimalstellen vorhanden wären 9) und die orange Linie ist genau die Hälfte davon. Es ist nicht überraschend, dass dies direkt im Hauptzweig des Diagramms liegt, da wir statistisch gesehen eine durchschnittliche Ziffer von 4,5 erwarten würden.

Die dünne Linie der Diagrammpunkte, die Sie unter dem Hauptast sehen, sind Brüche, die enden ...3333..., da sie alle sehr nahe beieinander liegen 3 N (N+1) / 2.


Sehr schöne Antwort, und ich liebe die Grafik! Es ist fast bedauerlich, dass dies nicht die kürzeste ist, und ich kann sie nicht als Antwort akzeptieren. :) Wenn ich nicht vergesse, könnte ich in zwei Tagen ein kleines Kopfgeld verdienen, weil ich so viel mehr beantworte als die einfache Aufgabe, die ich gegeben habe.
Kevin Cruijssen

1
@ KevinCruijssen Danke! :)
Martin Ender

6

05AB1E , 12 11 Bytes

Di<ë°¹÷.pSO

Probieren Sie es online! oder eine Testsuite für die ersten 50 Nummern.

Erläuterung

              # implicit input n
Di<           # if n == 1 then 0
   ë          # else
    °¹÷       # 10^n // n
       .p     # get prefixes
         SO   # sum digits

Eine effizientere Version, um große Zahlen mit TIO auszuprobieren

Der Unterschied zur kürzeren Version besteht darin, dass wir hier das Produkt der Ziffern und die Umkehrung ihres 1-basierten Index summieren, anstatt die Ziffern in Präfixen zu summieren.

Di<ë°¹÷SDgLR*O

Probieren Sie es online!


5

Java 8, 181 169 166 153 142 Bytes

import java.math.*;n->{int m=n+2,r=0,i;for(;m>2;)for(i=m--;i-->2;r+=(BigDecimal.ONE.divide(new BigDecimal(n),n,3)+"").charAt(i)-48);return r;}

Erläuterung:

Probieren Sie es hier aus.

import java.math.*;   // Required import for BigDecimal

n->{                  // Method with integer as both parameter and return-type
  int m=n+2,          //  Copy of the input-integer plus 2
      r=0,            //  Result-integer, starting at 0
      i;              //  Index-integer
  for(;m>2;)          //  Loop (1) as long as `m` is larger than 2
    for(i=m--;        //   Set index `i` to `m`, and decrease `m` by one afterwards
        i-->2;        //   Inner loop (2) from `m` down to 2 (inclusive)
      r+=             //    Add to the result-sum:
         (BigDecimal.ONE.divide(
                      //     1 divided by,
           new BigDecimal(n),
                      //     the input
           n,3)       //     With the minimal required precision
          +"")        //     Convert this to a String
          .charAt(i)  //     Take the character of this String at index `i`
          -48         //     And convert it to a number
     );               //   End of inner loop (2)
                      //  End of loop (1) (implicit / single-line body)
  return r;           //  Return result
}                     // End of method

4

PHP, 66 65 Bytes

for($b=$c=$argv[$a=1];$c;)$o+=$c--*(($a=10*($a%$b))/$b^0);echo$o;

Angepasst an diese Antwort (auch von mir): Aufteilung von nicht ganz so kleinen Zahlen und Jörg Hülsermanns Änderungsvorschlag dazu. Verwenden Sie wie:

php -r "for($b=$c=$argv[$a=1];$c;)$o+=$c--*(($a=10*($a%$b))/$b^0);echo$o;" 7

edit: korrigierte einen Fehler um +1 Bytes und faltete die Zuweisung von $ a in $ argv [1] für -2 Bytes für ein netto 1 Byte weniger.


3

Scala, 84 Bytes

val b=BigDecimal
def?(& :Int)=1 to&map(x=>(""+b(1)/b(&))slice(2,x+2)map(_-48)sum)sum

Ungolfed:

def f(n: Int)={
  val digits = ""+BigDecimal(1)/BigDecimal(n)
  (1 to n).map( x=>
    digits.slice(2, x+2).map(d => d - 48).sum
  ).sum

Erläuterung:

val b=BigDecimal   //define an alias for BigDecimal
def?(& :Int)=      //define a method called ? with an integer & as a parameter
  1 to &           //create a range from 1 to &
  map(x=>          //for each number x...
    (""+b(1)/b(&))   //calculate the fraction
    slice(2,x+2)     //and take the slice starting from the third element,
                     //(dropping the "1.") and containing x elements
    map(_-48)        //for each char, subtract 48 to get the integer value
    sum              //and sum them
  )sum             //and take the sum

Ich könnte ein paar Bytes einsparen, indem ich die Art und Weise ausnütze, wie der Compiler Token verwendet: Durch Aufrufen des Arguments &können Sie 1 to&mapanstelle von schreiben 1 to n map. Die gleiche Regel gilt für def?.


3

Jelly , 11 Bytes

’aµR⁵*:µDFS

TryItOnline
Erste 50

Zu langsam für die großen Testfälle.

Wie?

’aµR⁵*:µDFS - Main link: n
’           - decrement
 a          - and (to handle special case where n=1, to return 0 rather than 10)
  µ         - monadic chain separation
   R        - range: [1,2,...n]
    ⁵       - literal 10
     *      - exponentiation: [10,100,...,10^n]
      :     - integer division: [10//n,100//n,...,10^n//n]
       µ    - monadic chain separation
        D   - cast to a decimal list [[digits of 10//n],[digits of 100//n],...]
         F  - flatten into one list
          S - sum

2
Ich glaube, ich habe noch nie eine Gelee-Antwort gesehen, bei der die Erklärung eine gerade Linie ist ;-)
ETHproductions

Ich habe fast das R⁵*Äquivalent von links nach rechts gesetzt, aber dann die schöne gerade Linie gesehen :)
Jonathan Allan

3

PHP, 76 Bytes

(Edit -1 Byte - Danke user59178 - Deine Lösung ist noch besser)

for($c=substr(bcdiv(1,$a=$argv[1],$a),2);$i<$a;)$s+=($a-$i)*$c[$i++];echo$s;

Sie können ein Byte (ein Semikolon) speichern, indem Sie das $c=blahin den ersten Teil vonfor(;;)
user59178 bewegen.

2

MATL, 19 Bytes

li/GEY$4LQ)!UYsG:)s

Probieren Sie es online!

Erläuterung

l       % Push a 1 literal to the stack
i/      % Grab the input (n) and compute 1/n
GE      % Grab the input again and multiply by 2 (2n)
Y$      % Compute the first 2n digits of 1/n after the decimal
4LQ)    % Get only the digits past the decimal point
!U      % Convert to numbers
Ys      % Compute the cumulative sum
G:)     % Get the first n terms
s       % Sum the result and implicitly display

2

Groovy, 87 Bytes

Dies war weniger schmerzhaft als erwartet und basiert auf meiner Antwort hier :

{n->(1..n).collect{x->(1.0g.divide(n, n, 1)+"")[2..x+1].getChars().sum()-48*(x)}.sum()}

Erläuterung

1.0g - Verwenden Sie für die eine die BigDecimal-Notation.

.divide(n, n, 1)+"" - Mit n-Genauigkeit durch n teilen (nur BigDecimal-Funktion) und in str konvertieren.

(...)[2..x+1].getChars() - Ermittelt den Teilstring der aktuellen Iteration als Array von Zeichen.

.sum()-48*(x)- Summieren Sie die ASCII-Werte der Zeichen und reduzieren Sie sie für jedes Element um 48. Dadurch wird der Wert von einer ASCII-Ziffer in eine Ganzzahl umgewandelt, wodurch im Wesentlichen Byte eingespart werden *.toInteger().

(1..n).collect{...}.sum() - Durchlaufen Sie jede der Ziffern in der Division, indem Sie diese Funktion ausführen, und erhalten Sie sie alle in einem einzigen Array und einer Summe.

2 Bytes gespart und Effizienz geopfert ...

Dies ist eine effizientere Version, bei der BigDecimal nicht bei jeder Iteration neu berechnet wird.

{n->i=1.0g.divide(n, n, 1)+"";(1..n).collect{x->i[2..x+1].getChars().sum()-48*(x)}.sum()}

2

J, 27 Bytes

1#.[:+/\-{.10#.inv%<.@*10^]

Verwendung

Die Eingabe ist eine erweiterte Ganzzahl.

   f =: 1#.[:+/\-{.10#.inv%<.@*10^]
   (,.f"0) (>: i. 50x) , 24990x + i. 11
    1          0
    2         10
    3         18
    4         23
    5         10
    6         96
    7        103
    8         52
    9         45
   10         10
   11        270
   12        253
   13        402
   14        403
   15        630
   16        183
   17        660
   18        765
   19        819
   20         95
   21        975
   22       1034
   23       1221
   24       1500
   25         96
   26       1479
   27       1197
   28       1658
   29       1953
   30       1305
   31       1674
   32        321
   33        816
   34       2490
   35       2704
   36       4235
   37       2022
   38       3242
   39       2295
   40        268
   41       2944
   42       3787
   43       3874
   44       4097
   45       1980
   46       4380
   47       4968
   48       3424
   49       4854
   50         98
24990 1405098782
24991 1417995426
24992 1364392256
24993 1404501980
24994 1408005544
24995 1377273489
24996 1395684561
24997 1405849947
24998 1406216741
24999 1142066735
25000      99984

Die Leistung ist gut und benötigt nur ca. 3 Sekunden, um die großen Testfälle zu berechnen.

   timex 'f 7x'
0.000119
   timex 'f 24999x'
3.8823
   timex 'f 25000x'
3.14903

Erläuterung

1#.[:+/\-{.10#.inv%<.@*10^]  Input: n
                          ]  Get n
                       10^   Raise 10 to the nth power
                  %          Get the reciprocal of n
                      *      Multiply (1/n) with (10^n)
                   <.@       Floor it
           10#.inv           Convert it to a list of base 10 digits
        -                    Negate n
         {.                  Take the last n values from the list of digits
                             (This is to handle the case for n = 1)
   [:  \                     For each prefix of the list of digits
     +/                        Reduce it using addition to get the sum
1#.                          Convert those sums as base 1 digits and return
                             (This is equivalent to taking the sum)

2

Gelee , 10 Bytes

⁵*:⁸D+\_ỊS

Nicht der kürzeste Ansatz , aber ziemlich effizient. Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

⁵*:⁸D+\_ỊS  Main link. Argument: n (integer)

⁵*          Yield 10**n.
  :⁸        Divide 10**n by n (integer division).
    D       Convert the quotient to base 10.
     +\     Take the cumulative sum of the digits.
        Ị   Insignificant; yield (abs(n) <= 1).
       _    Subtract the resulting Boolean from each decimal digit.
            This takes care of edge case n = 1, which would return 2 otherwise.
         S  Take the sum.

1

Python 2, 90 Bytes

lambda o:sum([sum([int(i)for i in s])for s in map(lambda x:str(1.0/o)[2:x],range(3,3+o))])

Nicht hübsch, aber durch Float-Dividieren, Konvertieren in einen String und anschließende iterative Auswahl des String-Index, um das Dreieck der Zahlen zu erhalten, dann das Listenverständnis durchzuführen und jedes Zeichen in ein int zu konvertieren und schließlich alle zu summieren.


1

JavaScript (ES6), 47 Byte

f=(b,a=1%b,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

Wie es funktioniert

Diese Antwort zeigt eine Methode zur Berechnung der c- Dezimalstellen von a / b :

f=(a,b,c,d=".")=>~c?(a/b|0)+d+f(a%b*10,b,c-1,""):d

Dies ist ein hervorragender Ausgangspunkt für diese Herausforderung. Zuerst können wir es leicht ändern, so dass es b Dezimalstellen von 1 / b berechnet , indem wir die Parameter neu ordnen und die Standardeinstellungen festlegen:

f=(b,a=1,c=b,d=".")=>~c?(a/b|0)+d+f(b,a%b*10,c-1,""):d

Als nächstes können wir dies so ändern, dass es die Summe der ersten b Dezimalstellen berechnet , anstatt sie zu verketten (dies beseitigt den dParameter):

f=(b,a=1,c=b)=>~c?(a/b|0)+f(b,a%b*10,c-1):0

Wir sind fast an einer Lösung; Jetzt müssen wir nur noch jede Ziffer mit c + 1 multiplizieren :

f=(b,a=1,c=b)=>~c?(a/b|0)*-~c+f(b,a%b*10,c-1):0

Hmm, das scheint ein bisschen lang zu sein. Was ist, wenn wir c zunächst um 1 erhöhen?

f=(b,a=1,c=b+1)=>c?(a/b|0)*c+f(b,a%b*10,c-1):0

Das spart ein Byte. Und hier ist eine Möglichkeit, eine weitere zu sparen:

f=(b,a=1,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

Und jetzt haben wir unsere Antwort. f(7)ist 103, f(11)ist 270, f(1)ist ... 2? Oh, wir haben vergessen, den Fall zu berücksichtigen, in dem a / b bei der ersten Iteration 1 ist (d. H 1 ist b ist 1). Machen wir etwas dagegen:

f=(b,a=1%b,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

1 mod b ist immer 1 , außer b ist 1 , in diesem Fall ist es 0 . Unser Programm ist jetzt für alle Eingaben mit 47 Bytes korrekt .


1

Python 2, 49 Bytes

lambda n:sum(10**-~k/n%10*(n-k)for k in range(n))

Teste es auf Ideone .


0

C 53 Bytes

f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}

Unterhalb der Haupt für einige Test zu tun ...

//44,79
#define R return
#define F for
#define U unsigned
#define N int
#define B break
#define I if
#define L(i) for(;i-->0;)
#define J(a,b)  if(a)goto b
#define G goto
#define P printf
#define D double
#define C unsigned char
#define A getchar()
#define O putchar
#define M main
#define Y malloc
#define Z free
#define S sizeof
#define T struct
#define E else
#define Q static
#define X continue  
main()
{N  k, a=0, b=0, i;

 F(i=1;i<50;++i) 
       P("f(%u)=%u |", i, f(i,i,1,0));
 P("\n");
 F(i=24990;i<=25000;++i) 
       P("f(%u)=%u |", i, f(i,i,1,0));
 P("\n");
 R 0;
}

/*
f(1)=0 |f(2)=10 |f(3)=18 |f(4)=23 |f(5)=10 |f(6)=96 |f(7)=103 |f(8)=52 |f(9)=45
f(10)=10 |f(11)=270 |f(12)=253 |f(13)=402 |f(14)=403 |f(15)=630 |f(16)=183 |f(17)=660 
f(18)=765 |f(19)=819 |f(20)=95 |f(21)=975 |f(22)=1034 |f(23)=1221 |f(24)=1500
f(25)=96 |f(26)=1479 |f(27)=1197 |f(28)=1658 |f(29)=1953 |f(30)=1305 |f(31)=1674
f(32)=321 |f(33)=816 |f(34)=2490 |f(35)=2704 |f(36)=4235 |f(37)=2022 |f(38)=3242
f(39)=2295 |f(40)=268 |f(41)=2944 |f(42)=3787 |f(43)=3874 |f(44)=4097 |f(45)=1980
f(46)=4380 |f(47)=4968 |f(48)=3424 |f(49)=4854 |
f(24990)=1405098782 |f(24991)=1417995426 |f(24992)=1364392256 |f(24993)=1404501980
f(24994)=1408005544 |f(24995)=1377273489 |f(24996)=1395684561 |f(24997)=1405849947 
f(24998)=1406216741 |f(24999)=1142066735 |f(25000)=99984 
*/

Warum stimmt jemand ab? Liegt es an einem Fehler? liegt es daran, dass ich nicht das richtige min für ihn oder sie finde? Für mich ist diese Anzahl von Zeichen genug und okay, fühlen Sie sich frei, diese Antwort auch als die andere zu cacel, wo ich nicht sprechen kann
RosLuP

3
Wie andere Ihre Antworten kommentiert haben, besteht der Sinn des Codegolfs darin, den Code so kurz wie möglich zu halten , Sie fügen jedoch weiterhin eine Reihe von Makros ohne triftigen Grund hinzu. f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}ist nur 53 Bytes lang.
Dennis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.