Chcę, żeby moja książka była poza tym stołem


21

Fabuła

Mam więc książkę, którą chcę oddzielić od stołu przy pomocy innych książek. Chcę wiedzieć, ile książek potrzebuję do osiągnięcia tego przy długości książek.n

Oto wizualizacja, którą narysował dla mnie mój przyjaciel z Wolfram:

a visualization from Wolfram

Więcej informacji na ten temat w Wolfram i Wikipedii .

Wyzwanie

Biorąc pod uwagę liczbę całkowitą , wypisz, ile książek potrzebnych było, aby najwyższa książka znajdowała się n w odległości od książki w poziomie. lub Znajdź najmniejszą wartość całkowitą m dla wejścia n w następującej nierówności. m i = 1 1nn

mn

i=1m12in

Edycja: dla ułamków użyj co najmniej zmiennoprzecinkowego pojedynczej precyzji IEEE. przepraszam za edycję wyzwania po opublikowaniu

( OEIS A014537 )

Przypadki testowe

 1          4
 2         31
 3        227
 5      12367
10  272400600


Czy musi korzystać z tego konkretnego układu książek, który IIRC nie jest optymalny?
user253751

Odpowiedzi:


13

Oktawa , 41 40 33 bajtów

1 bajt zapisany dzięki @Dennis

@(n)find(cumsum(.5./(1:9^n))>n,1)

Wypróbuj online!

Wyjaśnienie

Wykorzystuje to fakt, że liczby harmoniczne mogą być ograniczone przez funkcję logarytmiczną.

Ponadto, >=porównanie może zostać zastąpiona >, ponieważ Liczby harmoniczne nie może być nawet całkowite (dzięki, @Dennis!).

@(n)                                   % Anonymous function of n
                     1:9^n             % Range [1 2 ... 9^n]
                .5./(     )            % Divide .5 by each entry
         cumsum(           )           % Cumulative sum
                            >n         % Is each entry greater than n?
    find(                     ,1)      % Index of first true entry


10

Łuska , 8 bajtów

V≥⁰∫m\İ0

Wypróbuj online!

Ponieważ Husk używa liczb wymiernych, kiedy jest to możliwe, nie ma to problemów z liczbą zmiennoprzecinkową

Wyjaśnienie

      İ0    The infinite list of positive even numbers
    m\      Reciprocate each
   ∫        Get the cumulative sum
V           Find the index of the first element
 ≥⁰         that is greater than or equal to the input

8 bajtów, ale w jakim zestawie znaków?
john16384

3
@ john16384 Husk ma własną stronę kodową, na której każdy symbol odpowiada jednemu bajtowi. Oto odpowiedni
zrzut heksowy



3

Szybki , 65 bajtów

func f(n:Double){var i=0.0,s=i;while s<n{i+=1;s+=0.5/i};print(i)}

Wypróbuj online!

Nie golfił

func f(n:Double) {
  var i = 0.0, s = 0.0
  while s < n {
    i += 1;
    s += 0.5 / i
  }
  print(i)
}


3

JavaScript (ES6), 34 bajty

n=>eval("for(i=0;n>0;n-=.5/i)++i")

Nie golfił

n => {
    for(i = 0; n > 0; ++i)
        n -= .5 / i
    return i;
}

Przypadki testowe


Wymyślono podobne rozwiązanie, używając rekurencji dla 30 bajtów. Nie wiem, czy opublikować, czy nie, po zobaczeniu swojego.
Kudłaty

1
Być może czegoś mi brakuje, ale dlaczego musisz zawinąć to w evaloświadczenie?
caird coinheringaahing

1
@cairdcoinherigaahing, bez zmienna musiałyby byćevalireturn ed na końcu, kosztem jeszcze kilka bajtów.
Kudłaty


2

Haskell, 71 49 48 bajtów

f x=length.fst.span(<x).scanl(+)0$(0.5/)<$>[1..]

@BMO uratowało mi aż 22 bajty!



2

TI-BASIC, 27 bajtów

Monituje użytkownika o dane wejściowe i wyświetla dane wyjściowe po zakończeniu. Uwaga: ⁻¹jest tokenem -1 (odwrotnym).

Input N
1
Repeat 2N≤Σ(I⁻¹,I,1,Ans
Ans+1
End
Ans

2
Jeśli masz zamiar zapisać Anssię Nod razu, to Input Nczy Prompt Njest to metoda wprowadzania że oszczędza na jeden bajt Ans→N. I Mmoże być zastąpiony przez Ans, dzięki czemu 1→Mstaje się 1i M+1→Mstaje Ans+1. (Ale jestem sceptycznie nastawiony do wyjścia, Ansktóre nie jest wyświetlane - zobacz to - więc może zakończenie :Ansjest odpowiednie: wtedy wartość zostanie pokazana zamiast „Gotowe”.)
Misha Lavrov

Dziękuję Ci! Wiedziałem, Ans→Nże czuję się zabawnie. Niezłe optymalizacje. Skorzystałem również z twoich rad dotyczących produkcji, aby być bezpiecznym. Nadal wychodzi z -3 bajtami netto: D
kamoroso94

1

05AB1E , 11 bajtów

XµN·zODI›}N

Wypróbuj online!

Wyjaśnienie

Xµ       }    # loop until counter is 1
  N·z         # push 1/(2*N)
     O        # sum the stack
      DI›     # break if the sum is greater than the input
          N   # push N


1

Japt , 12 bajtów

Ta sama długość co, ale nieco bardziej wydajna niż opcja rekurencyjna.

@T¨(Uµ½÷X}a1

Spróbuj


Wyjaśnienie

@T¨(Uµ½÷X}a1
                 :Implicit input of integer U
@        }a1     :Return the first number X >=1 that returns truthy when passed through the following function
 T               :Zero
  ¨              :Greater than or equal to
    Uµ           :Decrement U by...
      ½÷X        :0.5 divided by X

1

J, 22 bajty

-6 bajtów dzięki frownyfrog

I.~0+/\@,1%2*1+[:i.9&^

Wypróbuj online!

oryginalna odpowiedź

Odpowiedź Luisa w J:

1+]i.~[:<.[:+/\1%2*1+[:i.9&^

Nie golfił

1 + ] i.~ [: <. [: +/\ 1 % 2 * 1 + [: i. 9&^

Najbardziej ciekawy, czy można go radykalnie poprawić ( mile na kaszel )

Wyjaśnienie

1 +      NB. 1 plus... 
] i.~    NB. find the index of the arg in...
[: <.    NB. the floor of...
[: +/\   NB. the sumscan of...
1 %      NB. the reciprical of...
2 *      NB. two times...
1 +      NB. 1 plus...
[: i.    NB.  the integers up to 
9&^      NB. 9 raised to the power of the arg

Wypróbuj online!


1+]i.~[:<.-> 1+]I.~->I.~0,
FrownyFrog

ofc! dziękuję frownyfrog
Jonah

A potemI.~0+/\@,
FrownyFrog

Jeśli edytujesz,
pokonasz

@FrownyFrog, gotowe. jeśli masz trochę czasu, chciałbym zobaczyć, jak rozwiązujesz ten problem: codegolf.stackexchange.com/questions/154345/bracket-expansion . wszystkie rozwiązania, o których mogę pomyśleć, są zbyt gadatliwe, aby
Jonah

0

PHP, 35 bajtów

while($argv[1]>$s+=.5/++$i);echo$i;

Uruchom go za pomocą CLI:

$ php -d error_reporting=0 -r 'while($argv[1]>$s+=.5/++$i);echo$i;' 5


0

Java 8, 49 bajtów

n->{float r=0,s=0;for(;s<n;)s+=.5f/++r;return r;}

Wyjaśnienie:

Wypróbuj online. (Przekroczono limit czasu dla przypadków testowych powyżej n=7.)

n->{             // Method with integer parameter and float return-type
  float r=0,     //  Result-float, starting at 0
        s=0;     //  Sum-float, starting at 0
  for(;s<n;)     //  Loop as long as the sum is smaller than the input
    s+=.5f/++r;  //   Increase the sum by `0.5/(r+1)`,
                 //   by first increasing `r` by 1 with `r++`
  return r;}     //  Return the result-float

0

tinylisp , 98 bajtów

(load library
(d _(q((k # N D)(i(l N(* D # 2))(_(inc k)#(+(* N k)D)(* D k))(dec k
(q((#)(_ 1 # 0 1

Ostatni wiersz to nienazwana funkcja lambda, która pobiera liczbę długości książek i zwraca liczbę potrzebnych książek. Wypróbuj online!

Wyjaśnienie

Jedynym typem danych typu tinylisp są liczby całkowite, więc szereg harmonicznych obliczamy jako ułamek, śledząc licznik i mianownik. Na każdym kroku Njest licznikiem, Dmianownikiem i kindeksem sumy. Chcemy, aby nowa suma częściowa była N/D + 1/k, lub (N*k + D)/(D*k). W związku z tym powracamy z nowym licznikiem N*K + D, nowym mianownikiem D*ki nowym indeksemk+1 .

Rekurencja powinna zostać zatrzymana, gdy suma częściowa będzie większa lub równa #pożądanej liczbie długości książek. W tym momencie zaszliśmy o jedną książkę za daleko, więc wracamy k-1. Warunkiem jest 1/2 * N/D < #; mnożąc mianownik, otrzymujemyN < D*#*2 , co jest najbardziej golfowym sposobem na napisanie go.

Funkcja rekurencyjnego pomocnika _wykonuje wszystkie te obliczenia; główną funkcją jest tylko jeden argument, który wywołuje wrapper _z poprawnymi wartościami wyjściowymi dla k, Ni D.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.