Ile dostałeś prezentu na Boże Narodzenie?

32

Tak, jak dużo , a nie ile ...

Jak wszyscy wiemy, duży prezent jest znacznie lepszy niż mały. Dlatego wartość prezentów należy zawsze mierzyć w całkowitej objętości, a nie w ilości prezentów, wadze, a nawet w łącznej cenie.

Ponieważ nie ma nic przeciwko porównywaniu ilości prezentów, które się dostaje, nie potrzebujesz długiego skryptu, który będzie łatwo widoczny i czytany przez innych na przyjęciu bożonarodzeniowym. Dlatego musisz ograniczyć liczbę bajtów do skryptu.

Twoje zadanie jest proste: utwórz program, który pobiera listę wymiarów jako dane wejściowe, w dowolnym odpowiednim formacie, i generuje połączoną objętość prezentów. Wymiar każdego prezentu będzie albo zbiorem trzech liczb, albo pojedynczej liczby. Jeśli dane wejściowe to trzy liczby ( L, W, H), teraźniejszość jest prostopadłościanem wymiarów L x W x H. Jeśli jest to pojedyncza liczba ( R), teraźniejszość jest kulą o promieniu R.

Zasady:

  • Może to być pełny program lub funkcja
  • Dane wejściowe mogą być w dowolnym dogodnym formacie
    • Jeśli jest to pożądane, kula może być reprezentowana przez liczbę, po której następują dwa zera
    • Prostopadłościan zawsze będzie miał wszystkie niezerowe wymiary.
  • Dane wyjściowe powinny być pojedynczymi liczbami dziesiętnymi
    • Dodatkowe dane wyjściowe są akceptowane, o ile jest oczywiste, jaka jest odpowiedź
    • Dane wyjściowe muszą mieć co najmniej dwie cyfry po przecinku
    • Dane wyjściowe mogą być w standardowej formie / notacji naukowej, jeśli liczba jest większa niż 1000.
    • Jeśli twój język nie ma stałej Pi, odpowiedź powinna być dokładna do 9999.99.

Przykłady:

((1,4,3),(2,2,2),(3),(4,4,4))
197.0973    // (1*4*3 + 2*2*2 + 4/3*pi*3^3 + 4*4*4)

(5)
523.5988

(5,0,0)
523.5988

Tabela liderów

Fragment kodu na dole tego postu generuje katalog na podstawie odpowiedzi a) jako listy najkrótszych rozwiązań według języka oraz b) jako ogólnej tabeli wyników.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

## Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

## Perl, 43 + 2 (-p flag) = 45 bytes

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Stewie Griffin
źródło
3
Żadna dama nie dostaje kapelusza w jednym z tych zabawnych cylindrycznych pudełek ?
manatwork,
2
@manatwork, nie, wszystkie kobiety dostaną meloniki i możesz je łatwo dopasować do kuli = P
Stewie Griffin
1
Zakładam, że (5)to tylko częściowy przykład, a nasz kod musi się z tym pogodzić ((5)).
manatwork
2
Jeśli nasz wybrany język nie ma stałej Pi, ile wymagana jest precyzja?
Dennis,
1
@manatwork, + i * są OK, o ile nie oznaczają dodawania i mnożenia (lub innych operacji) w używanym języku.
Stewie Griffin,

Odpowiedzi:

10

Galaretka , 19 18 bajtów

Zµ*3×1420÷339Ḣo@PS

Wypróbuj online!

Niestety, Jelly nie ma jeszcze stałej π , a wektoryzator nie obsługuje poprawnie pływaków.

Aby rozwiązać te problemy, zamiast mnożenia przez 4π / 3 , mnożymy przez 1420 i dzielimy przez 339 . Ponieważ 1420 ÷ 339 = 4.18879056… i 4π / 3 = 4.18879020… , jest to wystarczająco precyzyjne, aby zachować zgodność z przepisami.

Najnowsza wersja Jelly mogła wykonać to zadanie w 14 bajtach z większą precyzją.

Zµ*3×240°Ḣo@PS

Wypróbuj online!

Jak to działa

Zµ*3×1420÷339Ḣo@PS  Left argument: A, e.g., [[1, 2, 3], [4, 0, 0]]

Z                   Zip A; turn A into [[1, 4], [2, 0], [3, 0]].
 µ                  Begin a new, monadic chain with zip(A) as left argument.
  *3                Cube all involved numbers.
    ×1420           Multiply all involved numbers by 1420.
         ÷339       Divide all involved numbers by 339.
                    This calculates [[4.19, 268.08], [33.51, 0], [113.10, 0]]
             Ḣ      Head; retrieve the first array.
                    This yields [4.19, 268.08].
                P   Take the product across the columns of zip(A).
                    This yields [6, 0].
              o@    Apply logical OR with swapped argument order to the results.
                    This replaces zeroes in the product with the corresponding
                    results from the left, yielding [6, 268.08].
                 S  Compute the sum of the resulting numbers.

Wersja niekonkurencyjna używa ×240°zamiast tego ×1420÷339, który mnoży przez 240 i przekształca produkty w radiany.

Dennis
źródło
9

Haskell, 40 bajtów

q[x]=4/3*pi*x^^3
q x=product x
sum.map q

Przykład użycia: sum.map q $ [[1,4,3],[2,2,2],[3],[4,4,4]]-> 197.09733552923254.

Jak to działa: Dla każdego elementu listy wejściowej: jeśli ma pojedynczy element, xoblicz objętość kuli, w przeciwnym razie weź product. Podsumowując.

nimi
źródło
1
Czy ten sposób liczenia bajtów jest ogólnie poprawny? Powiedziałbym p=sum.map q(a potem kazałem użyć pna liście numerów)
Leif Willerts
1
@LeifWillerts: Istnieje najnowszy temat dotyczący meta, który umożliwia korzystanie z nienazwanych funkcji, które opierają się na definicjach globalnych. sum.map qjest nienazwaną funkcją, która zależy od q, więc myślę, że jest w porządku.
nimi
9

Pyth, 19 18 bajtów

sm|*Fd*.tC\ð7^hd3Q

1 bajt dzięki Dennisowi

Demonstracja

Format wejściowy to lista list:

[[1,4,3],[2,2,2],[3,0,0],[4,4,4]]

Po prostu mnoży wymiary razem, aby obliczyć objętość kostki. Jeśli osiągnie zero, oblicza objętość kuli.

Stała kuli 4/3*piobliczana jest w radianach jako 240 stopni. .t ... 7konwertuje dane wejściowe w stopniach na radiany i C\ðoblicza punkt kodowy ð, który wynosi 240.

isaacg
źródło
7

Python 2, 86 70 bajtów

lambda i:sum(x[0]*x[1]*x[2]if len(x)>1 else x[0]**3*4.18879for x in i)
TFeld
źródło
Mam bajt liczony jako 86, skąd masz swój?
wnnmaw,
Dodatkowo możesz zaoszczędzić bajty po prostu ręcznie wprowadzając wartość pi, możesz użyć do, 3.14159265358979323aby wyrównać
wnnmaw
@wnnmaw Zapomniałem policzyć import -.-
TFeld
Wierzę, że twoja zakodowana wartość dla pi jest trochę
zła
4
@wnnmaw That's not Pi; to 4Pi / 3.
Dennis,
5

Mathematica, 34 bajty

Tr[1.##&@@@(#/.{r_}:>{4r^3/3Pi})]&

Nienazwana funkcja, która pobiera zagnieżdżoną listę długości i zwraca wolumin jako liczbę rzeczywistą.

Najpierw zamieniamy pojedyncze wartości na objętość odpowiedniej kuli za pomocą /.{r_}:>{4r^3/3Pi}. Następnie pomnożymy zawartość każdej listy przez 1.##&@@@. Na koniec obliczamy sumę jako ślad wektora za pomocą Tr[...].

Martin Ender
źródło
5

JavaScript (ES6), 56

l=>l.map(([x,y,z])=>t+=y?x*y*z:x*x*x*4/3*Math.PI,t=0)&&t

Bardziej sensowna .reduce wersja jest dłuższa o 1 bajt

l=>l.reduce((t,[x,y,z])=>t+(y?x*y*z:x*x*x*4/3*Math.PI),0)
edc65
źródło
Możesz zaoszczędzić kilka bajtów, używając 4.11879zamiast 4/3*Math.PI, ponieważ powinno to być wystarczająco dokładne, aby się zakwalifikować.
ETHproductions
@ETHproductions tak, ale In case your language doesn't have a Pi-constant,mój język ma stałą PI, więc nie wiem, czy się kwalifikuje
edc65
5

Python, 49 bajtów

lambda l:sum(a*b*c or a**3*4.18879for a,b,c in l)

Używa reprezentacji sfer jako (a,0,0). Traktowany jako prostopadłościan ma objętość 0, w którym to przypadku stosuje się objętość kuli. Nie jestem pewien, jak dokładna musi być stała, więc mam nadzieję, że to wystarczy.

xnor
źródło
4

MATL , 20 bajtów

it!ptbw~)3^4*3/XT*hs

Format wejściowy to macierz, w której każdy wiersz opisuje sześcian lub kulę. Kula jest zdefiniowana tylko przez pierwszą liczbę w tym rzędzie; pozostałe dwie liczby są równe zero. Tak więc pierwszym przykładem wyzwania byłoby:

[1 4 3; 2 2 2; 3 0 0; 4 4 4]

Wykorzystuje bieżącą wersję języka 2.0.2 , która jest wcześniejsza niż to wyzwanie.

Przykłady:

>> matl it!ptbw~)3^4*3/XT*hs
> [1 4 3; 2 2 2; 3 0 0; 4 4 4]
197.0973355292326

>> matl it!ptbw~)3^4*3/XT*hs
> [5 0 0]
523.5987755982989

Wyjaśnienie:

i             % input matrix
t!            % duplicate and transpose: each object is now a column
p             % product of elements in each column
t             % duplicate                                               
b             % bubble up top-third element in stack                              
w             % swap top two elements in stack                                  
~             % logical 'not'. This gives logical index of speheres                 
)             % reference () indexing. This is a logical-linear index to get sphere radii
3^4*3/XT*     % formula for volume of spehere; element-wise operations
h             % horizontal concatenation                                
s             % sum                
Luis Mendo
źródło
3

Prolog, 115 100 bajtów

Kod:

[]*0.
[[L,W,H]|T]*V:-W=0,X is 4*pi*L^3/3,T*Y,V is X+Y;X is L*W*H,T*Y,V is X+Y.
p(L):-L*V,write(V).

Wyjaśnił:

[]*0.
[[L,W,H]|T]*V:-W=0,                           % When 2nd dimension is 0
                  X is 4*pi*L^3/3,            % Calc volume of sphere
                  T*Y,                        % Recurse over list
                  V is X+Y                    % Sum volumes
                  ;                           % When we have a cube
                  X is L*W*H,                 % Calc cube volume
                  T*Y                         % Recurse over list
                  V is X+Y.                   % Sum volumes
p(L):-L*V,                                    % Get combined volume of list of lists
      write(V).                               % Print volume

Przykłady:

p([[1,4,3],[2,2,2],[3,0,0],[4,4,4]]).
197.09733552923257

p([[5,0,0]]).
523.5987755982989

Wypróbuj online tutaj

Edycja: zapisano 15 bajtów, definiując predykat dyadyczny.

Emigna
źródło
3

Perl, 52 47 bajtów

s/,/*/g||s@$@**3*4.18879@,$\+=eval for/\S+/g}{

46 + 1 za -p(to było powszechne; daj mi znać, jeśli tutaj jest inaczej, a ja zaktualizuję)

Sposób użycia: wstaw do pliku i echo 1,4,3 2,2,2 3 4,4,4 | perl -p x.pl

Z komentarzami:

s/,/*/g                # x,y,z becomes x*y*z
||                     # if that fails,
s@$@**3*1420/339@      # x becomes x**3 * 1420/339
,                      # 
$\+=eval               # evaluate the expression and accumulate
for/\S+/g              # iterate groups of non-whitespace
}{                     # -p adds while(<>){...}continue{print}; resets $_

aktualizacja 47 Podziękowania dla @Dennis za zapisanie niektórych bajtów przy użyciu tej sztuczki .

Kenney
źródło
s/,/*/g||s@$@**3*4.18879@,$\+=eval for/\S+/g;}{oszczędza kilka bajtów.
Dennis,
@Dennis Thanks! Próbowałem wcześniej z $ \, ale zresetowanie $_kosztowało tyle samo. Nadal nie jest jasne, dlaczego $_jest resetowany w nowym bloku. Czy $_blok jest lokalny while(<>){}?
Kenney,
Tak, $_jest domyślną zmienną bieżącego zakresu. W bloku END jest niezdefiniowany.
Dennis,
2

CJam, 24 21 bajtów

q~{3*)4P*3/*+3<:*}%:+

Sprawdź to tutaj.

Wyjaśnienie

q~       e# Read and evaluate input.
{        e# Map this block over the list of presents...
  3*     e#   Repeat the list of lengths 3 times. This will expand cuboids to 9 elements
         e#   and spheres to three copies of the radius.
  )      e#   Pull off the last element.
  4P*3/* e#   Multiply by 4 pi / 3.
  +      e#   Add it back to the list of lengths.
  3<     e#   Truncate to 3 elements. This is a no-op for spheres, which now have three
         e#   elements [r r 4*pi/3*r] but discards everything we've done to cuboids, such
         e#   that they're reduced to their three side lengths again.
  :*     e#   Multiply the three numbers in the list.
}%
:+       e# Sum all the individual volumes.
Martin Ender
źródło
2

PowerShell, 67 bajtów

($args|%{($_,((,$_*3)+4.18879))[$_.count-eq1]-join'*'})-join'+'|iex

Tutaj dzieje się jakaś czarna magia. Spróbuję przejść przez to płynnie.

Najpierw bierzemy nasze dane wejściowe, oczekiwane np. Jako pojedyncze tablice rozdzielane przecinkami (1,4,3) (2,2,2) (3) (4,4,4), i umieszczamy je w pętli |%{}.

Wewnątrz pętli najpierw sprawdzamy, czy $_konkretna tablica, którą bierzemy pod uwagę, ma tylko jeden element i używamy tego do indeksowania w tablicy (zasadniczo krótszej konstrukcji if / else). Jeśli jest to więcej niż jeden element, przypuśćmy, że (1,4,3)jako dane wejściowe, wykonujemy pierwszą połowę, która polega po prostu na wyplucie tablicy $_, np (1,4,3). W przeciwnym razie tworzymy nową tablicę dynamiczną składającą się z elementu trzykrotnie z (,$_*3)przybliżeniem 4/3 * Pi. W przypadku danych wejściowych (3)spowoduje to wynik (3,3,3,4.18879).

Tak, PowerShell ma stałą Pi, dostępną poprzez wywołanie .NET [math]::PI, ale to dłużej i nie chcę jej używać. : p

Niezależnie od tego łączymy tablicę wyjściową z gwiazdkami za pośrednictwem -join'*', więc "1*4*3". Po całkowitym przejściu przez pętlę mamy teraz kolekcję ciągów. Wszyscy -join'+'razem dla naszego dodania i iexwyrażenia do obliczenia wyniku.

Uff

AdmBorkBork
źródło
1

Ruby, 58 znaków

->b{b.reduce(0){|t,s|a,b,c=*s;t+(c ?a*b*c :a**3*4.18879)}}

Przykładowy przebieg:

2.1.5 :001 ->b{b.reduce(0){|t,s|a,b,c=*s;t+(c ?a*b*c :a**3*4.18879)}}[[[1,4,3],[2,2,2],[3],[4,4,4]]]
 => 197.09733

Ruby, 50 znaków

Poprawa pomysł bezczelnie skradzione z edc65 „s JavaScript odpowiedź .

->b{t=0;b.map{|a,b,c|t+=c ?a*b*c :a**3*4.18879};t}

Przykładowy przebieg:

2.1.5 :001 > ->b{t=0;b.map{|a,b,c|t+=c ?a*b*c :a**3*4.18879};t}[[[1,4,3],[2,2,2],[3],[4,4,4]]]
 => 197.09733
człowiek w pracy
źródło
1

Japt, 27 22 bajtów

N®r*1 ª4/3*M.P*Zg ³} x

Pobiera dane wejściowe jako tablice rozdzielone spacjami. Wypróbuj online!

Jak to działa

N®   r*1 ª 4/3*M.P*Zg ³  } x
NmZ{Zr*1 ||4/3*M.P*Zg p3 } x

          // Implicit: N = array of input arrays
NmZ{   }  // Map each item Z in N to:
Zr*1      //  Reduce Z with multiplication.
||4/3*M.P //  If this is falsy, calculate 4/3 times Pi
*Zg p3    //  times the first item in Z to the 3rd power.
x         // Sum the result.
          // Implicit: output last expression
ETHprodukcje
źródło
1

Pip , 23 bajty

{$*a|4/3*PI*@a**3}MSg^s

Istnieje kilka sposobów na przekazanie danych wejściowych do tego programu. Może przyjmować każdy prezent jako argument wiersza poleceń trzech liczb oddzielonych spacjami (które będą musiały być ujęte w cudzysłowy:) pip.py present.pip "1 4 3" "3 0 0". Alternatywnie, określ -rflagę i podaj każdy prezent jako linię standardu składającą się z trzech liczb oddzielonych spacją. Wypróbuj online!

W jaki sposób?

                         g is list of cmdline args (or lines of stdin, if using -r flag)
                         s is space, PI is what it says on the tin (implicit)
                    g^s  Split each argument on spaces, so we have a list of lists
{                }MS     Map this function to each sublist and sum the results:
 $*a                      Fold the list on * (i.e. take the product)
    |                     Logical OR: if the above value is zero, use this value instead:
     4/3*PI*              4/3 pi, times
            @a            First element of the list
              **3         Cubed
                         Autoprint the result
DLosc
źródło
0

Perl 5, 142 bajtów

Uruchom z -pwiersza polecenia i wpisz liczby rozdzielane przecinkiem, tak jak poniżej:

5,0,0 lub (5,0,0)

produkuje

523.598820058997

W piPerlu nie ma słowa kluczowego. Jest to w większości przypadków zgodne z określonymi liczbami znaczącymi, jednak nawet gdybym wpisał wszystkie liczby pi, które znam, nie byłoby to bardzo dokładne dla niektórych obliczeń. Więc zostawiłem to z 3.1415. Nie jestem pewien, czy jest to dopuszczalne, czy nie.

Kod:

@a=$_=~/(\d+,*)/g;$_=0;@n = map(split(/\D/),@a);for($i=0;$i<$#n;$i+=3){$x=$n[$i];$n[$i+1]==0?$_+=1420/339*$x**3:$_+=($x*$n[$i+1]*$n[$i+2]);}

Edytowane dla większej precyzji za radą Dennisa, który jest lepszy w podstawowej matematyce ode mnie, oraz z sugestii Michaela, aby zaoszczędzić bajty przy jednoczesnym zachowaniu precyzji.

Codefun64
źródło
2
1. Jak byś parsował 1511? 2. 3.1415 nie jest odpowiednio zaokrąglony ani wystarczająco precyzyjny. Jeśli moje obliczenia są prawidłowe, błąd nie może być większy niż 0,0000017 . 3. (4/3)*3.1415można zastąpić jednym pływakiem.
Dennis,
1. OP mówi, że możemy założyć końcowe zero dla sfer (co w rzeczywistości jest przykładowym wprowadzeniem, które podałem), 2. Nie wiem, jakich obliczeń używasz, ale na pewno zwiększę precyzję i 3 Dobra sugestia, tęskniłem za tym. Dzięki!
Codefun64
W tej chwili nie mam przed sobą zasobów, ale zastanawiam się, czy zrobienie 1420/339tego dałoby ci kilka bajtów z rozsądnym przybliżeniem. (jest to 4/3 * 355/113). Różnica między ułamkiem a wartością, którą masz, wynosi -8,49130615e-8
@MichaelT To jest najbardziej interesująca rzecz. Czy masz skrypt, który znajduje najmniejszą ułamkową reprezentację liczb? ;)
Codefun64
Codefun64 Właśnie opracowałem inne popularne przybliżenie dla pi. 22/7 nie mieści się w wystarczającej tolerancji, więc spojrzałem na en.wikipedia.org/wiki/Approximations_of_%CF%80 i użyłem następnego, aby sprawdzić, czy ma tolerancję lepszą niż to, o co prosił @Dennis.
0

Lua, 115 104 bajtów

function f(a)b=0 for i=1,#a do c=a[i]b=b+(1<#c and c[1]*c[2]*c[3]or(4/3)*math.pi*c[1]^3)end return b end

Proste rozwiązanie, muszę owinąć operację pseudo-trójskładnikową <condition> and <non-false> or <value if false>w nawiasach, w przeciwnym razie b sumowałoby się z oboma obszarami.

Dane wejściowe muszą być w formie, array={{1,4,3},{2,2,2},{3},{4,4,4}}a wynik można zobaczyć wykonując print(f(array)).

Katenkyo
źródło
0

05AB1E , 18 16 bajtów

εDgi3m4žq*3/*]PO

Wypróbuj online.

Wyjaśnienie:

ε                # Map each inner list of the (implicit) input to:
 D               #  Duplicate the current inner list
  gi             #  Is the length 1 (is it an `R`):
    3m           #   Take the duplicated current item and take its cube
                 #    i.e. [3] → [27]
      žq         #   PI
        4*       #   Multiplied by 4
          3/     #   Divided by 3
                 #    → 4.1887902047863905
            *    #   And multiply it with the current cubed `R`
                 #    [27] and 4.1887902047863905 → [113.09733552923254]
]                # Close both the if and map
 P               # Take the product of each inner list
                 #  i.e. [[1,4,3],[2,2,2],[113.09733552923254],[4,4,4]]
                 #   → [12,8,113.09733552923254,64]
  O              # Take the total sum (and output implicitly)
                 #  i.e. [12,8,113.09733552923254,64] → 197.09733552923254
Kevin Cruijssen
źródło
0

R, 38 36 bajtów

function(x,y=4*pi/3*x,z=x)sum(x*y*z)

Używa domyślnych argumentów do przełączania między przypadkami: z trzema argumentami oblicza produkt, a z jednym argumentem oblicza formułę kuli.

JDL
źródło
potrzebujesz f<-i {}?
Giuseppe
Ten kod nie wyświetla się poprawnie w przypadku testowym (5,0,0). Ponadto nie uwzględnia przypadku testowego, w którym jest wiele prezentów, a objętości należy zsumować.
Robert S.
Dla (5,0,0) dostaję zero - czy to nieprawda? Edytowałem, aby użyć sum(i usunąłem rzeczy, które nie były konieczne zgodnie z sugestią Giuseppe)
JDL