Convertitore di temperatura


38

Questa è una sfida di dimensioni in byte in cui devi convertire una temperatura di ingresso in una delle tre unità (Celsius, Kelvin e Fahrenheit) nelle altre due.

Ingresso

Ti verrà fornita una temperatura come numero seguito da un'unità (separata dallo spazio). La temperatura può essere un numero intero o un numero in virgola mobile (23 vs 23.0 o 23.678).

È possibile inviare una funzione o un programma completo che legge la stringa separata dallo spazio dall'argomento STDIN / ARGV / function o dall'equivalente più vicino e stampa l'output su STDOUT o sull'equivalente più vicino.

Produzione

L'output dovrebbe essere la temperatura convertita negli altri due formati, separati da una nuova riga e seguiti dal carattere di unità corrispondente su ciascuna riga (facoltativamente separato da uno spazio). L'ordine delle due unità non ha importanza.

Precisione di uscita

  • Il numero convertito deve essere accurato con almeno 4 cifre decimali senza arrotondamento.
  • Gli zero finali o i decimali sono opzionali purché i primi 4 decimali (senza arrotondamento) siano precisi. Puoi anche saltare i 4 zeri e / o il punto decimale nel caso in cui la risposta effettiva abbia 4 zeri dopo il punto decimale.
  • Non dovrebbero esserci zero iniziali
  • Qualsiasi formato numerico è accettabile purché soddisfi i tre requisiti di cui sopra.

Rappresentazione dell'unità

L'unità di temperatura può essere solo una delle seguenti:

  • C per Celsius
  • K per Kelvin
  • F per Fahrenheit

Esempi

Ingresso:

23 C

Produzione:

73.4 F
296.15 K

Ingresso:

86.987 F

Produzione:

303.6983 K
30.5483 C

Ingresso:

56.99999999 K

Produzione:

-216.1500 C
-357.0700 F

Questo è quindi vince l'ingresso più breve in byte! Buon golf!

Classifica

<script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 50740</script><script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


Presumo che le uscite possano essere in qualsiasi ordine. È accettabile l'output di tutti e tre i formati, ad esempio 23C\n73.4F\n296.15K ? o deve essere soppresso il formato di input?
Level River St,

@steveverrill il bit dell'ordine è menzionato nella sezione output. Devi solo produrre gli altri due formati.
Ottimizzatore

Informazioni sulla precisione dell'output: 2/3=> 0.666666666666è preciso alla 4a cifra? (Direi SÌ). O dovrebbe essere 0.6667?
edc65,

@ edc65 0.666666666666è corretto. Sto imponendo una precisione basata sull'arrotondamento. così 0.6666è l'alternativa.
Ottimizzatore

1
@Dennis nell'output, non esiste alcuna regola per stampare lo spazio o meno. Ma sarà presente nell'input.
Ottimizzatore

Risposte:


13

CJam, 77 65 60 59 55 54 52 byte

l~2|"459.67+1.8/'K 273.15-'C 1.8*32+'F"S/m<{~N2$}%6<

Provalo online nell'interprete CJam .

Come funziona

l~    e# Read and evaluate the input: F, K, C -> 15, 20, 12
2|    e# Bitwise OR with 2: F, K, C -> 15, 22, 14 = 0, 1, 2 (mod 3)

"459.67+1.8/'K 273.15-'C 1.8*32+'F"S/

      e# Push ["459.67+1.8/K" "273.15-C" "1.8*32+F"].
      e# These commands convert from F to K, K to C and C to F.

m<    e# Rotate the array of commands by 15, 22 or 14 units to the left.
{     e# For each command:
  ~   e#     Execute it.
  N   e#     Push a linefeed.
  2$  e#     Copy the temperature for the next iteration.
}%    e# Collect all results in an array.
6<    e# Keep only the first 8 elements.

32

Python 3, 118 116 byte

I=input()
t=eval(I[:-1])
u=ord(I[-1])%7
exec("u=-~u%3;t=[t*1.8-459.67,(t-32)/1.8,t+273.15][u];print(t,'FCK'[u]);"*2)

Esegue le conversioni in un ordine rotativo K -> F -> C -> Kdue volte.


43
Devi amare 'FCK'[u].
Alex A.

11
Ahah che diamine, ragazzi. Valuti la domanda e le risposte, non il mio stupido commento. : P
Alex A.

10

JavaScript ( ES6 ), 127 130 132 byte

In attesa di una straordinaria risposta esolanguage, non ho trovato molto da golf qui.

Utilizzando la stringa di modello, le 3 nuove righe sono significative e contate.

Esegui lo snippet in Firefox per testarlo.

F=x=>([t,u]=x.split(' '),z=273.15,y=9/5,u<'F'?`${t*y+32} F
${+t+z} K`:u<'K'?`${t=(t-32)/y} C
${t+z} K`:`${t-=z} C
${t*y+32} F`)

// Predefined tests

;['23 C','86.987 F','56.99999999 K']
.forEach(v=>O.innerHTML += v+' ->\n'+F(v)+'\n\n')
<input id=I><button onclick='O.innerHTML=F(I.value)'>-></button><br>
<pre id=O></pre>


7

Pip, 58 57 byte

Ft"CFK"RMbP(a-(o:[32i273.15]Ab%7))*$/95@A[tb]+(oAt%7).s.t

Accetta input dagli argomenti della riga di comando.

Formattato e leggermente non golfato:

o:[32 0 273.15]
F t ("CFK" RM b)
  P (a - o@(Ab % 7))
    * "95"@At / "95"@Ab
    + o@(At%7)
    . s . t

Spiegazione:

La formula di conversione generale tra unità 1 e unità 2 è temp2 = (temp1 - offset1) * mult2 / mult1 + offset2. Gli offset potrebbero essere allo zero assoluto o a qualsiasi altra temperatura conveniente; usiamo 0 ° C.

Unità Mult Offset
C 5 0     
K 5 273,15
F 9 32    

Costruiremo elenchi di questi valori e li indicizzeremo in base all'unità con cui abbiamo a che fare. Pip non ha matrici / hash / dizionari associativi, quindi abbiamo bisogno di convertire i caratteri in indici interi. Forse ci saranno schemi utili con i valori ASCII.

Unità Asc A% 2 Mult A% 7 A% 7% 3 Offset
C 67 1 5 4 1 0
K 75 1 5 5 2 273,15
F 70 0 9 0 0 32

Sembra promettente. Un altro fatto utile: gli indici in Pip si chiudono. Quindi non abbiamo realmente bisogno %3finché ci indicizziamo in qualcosa di lunghezza 3. Definire o:[32 0 273.15]e usare (o (Ab)%7)farà il trucco. ( Aottiene il valore ASCII di un carattere. La (l i)sintassi viene utilizzata per indicizzare in iterabili, nonché per le chiamate di funzione.)

Per i moltiplicatori, abbiamo solo bisogno dei due numeri 9 e 5. Dato che i numeri sono uguali alle stringhe in Pip, e quindi sono indicizzabili, ottenere il moltiplicatore è semplice come 95@Ab(usando l'altro metodo di indicizzazione, l' @operatore).

Usando le funzionalità di programmazione di array di Pip, possiamo salvare un personaggio con il metodo ingenuo:

95@At/95@Ab
$/95@A[tb]    Make a list of t and b, apply 95@A(...) to each item, and fold on /

Infine, aggiungi l'offset per la nuova unità, concatena uno spazio e il simbolo della nuova unità sull'estremità e stampa.

Lo facciamo per ciascuna tentrata "CFK" RM b, convertendola così in ogni unità tranne l'originale.

Invocazione di esempio:

C:\Golf> pip.py tempConv.pip 86.987 F
30.548333333333332 C
303.6983333333333 K

(Per ulteriori informazioni su Pip, consultare il repository .)


6

dc, 102 byte

Sono abbastanza sicuro che questo possa essere giocato di più, ma ecco un inizio:

4k[9*5/32+dn[ F
]n]sf[459.67+5*9/dn[ K
]n]sk[273.15-1/dn[ C
]n]sc[rlfxlkxq]sC[lkxlcxq]sF?dC=CF=Flcxlfx

dc fa appena il voto su questo. In particolare la gestione delle stringhe cc non è davvero all'altezza del lavoro. Ma tutto ciò che dobbiamo fare è distinguere tra "C", "F" e "K". Fortunatamente dc analizza "C" e "F" come numeri esadecimali 12 e 15. E per "K" lascia solo 0 in pila.

Produzione:

$ dc -f tempconv.dc <<< "23 C"
73.4000 F
296.1500 K
$ dc -f tempconv.dc <<< "86.987 F"
303.6983 K
30.5483 C
$ dc -f tempconv.dc <<< "56.99999999 K"
-216.1500 C
-357.0700 F
$

5

C, 160 byte

float v,f[]={1,1.8,1},d[]={0,32,273.15};u,t,j;main(){scanf("%f %c",&v,&u);for(u=u/5-13,v=(v-d[u])/f[u];j<2;)t=(++j+u)%3,printf("%f %c\n",f[t]*v+d[t],"CFK"[t]);}

Questo si legge dallo stdin. Non viene specificata la precisione dell'output, quindi stampa ciò che si printf()sente come la stampa, che è per lo più di 4 cifre.

Versione non golfata:

#include <stdio.h>

float v, f[] = {1.0f, 1.8f, 1.0f}, d[] = {0.0f, 32.0f, 273.15f};
char u;
int t, j;

int main() {
    scanf("%f %c", &v, &u);
    u = u / 5 - 13;
    v = (v - d[u]) / f[u];
    for( ; j < 2; ) {
        t = (++j + u) % 3;
        printf("%f %c\n", f[t] * v + d[t], "CFK"[t]);
    }

    return 0;
}

Alcune spiegazioni / osservazioni:

  • Questo si basa su tabelle di ricerca fe dcontiene i fattori di moltiplicazione e gli offset per convertire Celsius in qualsiasi altra unità (incluso Celsius stesso, per evitare casi speciali).
  • Se uè l'unità di input, u / 5 - 13esegue il mapping Csu 0, Fsu 1 e Ksu 2.
  • L'input viene sempre convertito in Celsius.
  • Il ciclo scorre le due unità che non sono l'input e converte il valore Celsius in quella unità.
  • La versione golfata utilizza una intvariabile anziché una charvariabile per ricevere l' scanf()input. Questa è una mancata corrispondenza del tipo, che produrrà risultati corretti solo su macchine little endian (che è quasi tutte al giorno d'oggi).

Ridotto a 152: float v,f[]={1,1.8,1,0,32,273.15};u;main(j){scanf("%f %c",&v,&u);for(u=u/4&3,v-=f[u+3],v/=f[u];j++<3;printf("%f %c\n",f[u]*v+f[u+3],"CFK"[u]))u++,u%=3;}. Guadagnato un po 'con meno variabili, spostando il codice. La nuova ipotesi è argc = 1 (j = 1). u = u/4 & 3.
domen,

4

Python 2, 168 byte

Ho visto la soluzione Python 3 proprio mentre stavo per pubblicare questo, ma qualunque cosa, sto solo praticando il golf.

s=raw_input().split();v=eval(s[0]);c,t=(v-32)/1.8,v-273.15
print[["%fC\n%fF"%(t,t*1.8+32),"%fK\n%fC"%(c+273.15,c)][s[1]=="F"],"%fK\n%fF"%(v+273.15,v*1.8+32)][s[1]=="C"]

Ungolfed:

def conv(s):
    s = s.split()
    v = float(s[0])
    if s[1]=="C":
        print "%f K\n%f F"%(v+273.15,v*1.8+32)
    elif s[1]=="F":
        v = (v-32)/1.8
        print "%f K\n%f C"%(v+274.15,v)
    else:
        c = v-273.15
        print "%f C\n%f F"%(c,c*1.8+32)

3

Perl, 85 80 76

#!perl -nl
print$_=/C/?$_+273.15." K":/K/?$_*9/5-459.67." F":5/9*($_-32)." C"for$_,$_

Metti alla prova me .


3

PHP, 161 153

function f($i){list($v,$u)=split(" ",$i);$u==C||print($v=$u==K?$v-273.15:($v-32)*5/9)."C\n";$u!=K&&print $v+273.15 ."K\n";$u!=F&&print $v*9/5+32 ."F\n";}

http://3v4l.org/CpvG7

Sarebbe bello giocare a golf altri due personaggi per entrare nella top ten ...


Bene tecnicamente, in base alle regole, non è necessario che ci siano spazi tra l'unità e la sua temperatura in uscita. Secondo il mio calcolo che salva 3 byte.
Kade,

Un buon punto :-) Ho anche trovato un modo per riutilizzare una variabile, che ne salva un'altra manciata.
Stephen,

Soluzione lunga 135 byte: sandbox.onlinephpfunctions.com/code/… . Fondamentalmente: rimosso \ne modificato in nuove righe reali, convertito in un programma completo (ricezione dei dati tramite GET, ad esempio:) http://localhost/my_file.php?t=<temperature>e sostituito $u!=Kcon $u^Ke $u!=Fcon $u^F. Se $uè K, corsa $u^Krestituirà una stringa vuota, che è un valore falsy. Inoltre, il tuo spazio all'interno della divisione è stato convertito in C^c(Solo per sembrare interessante).
Ismael Miguel,

3

Python 2, 167

s=raw_input();i=eval(s.split()[0]);d={"C":"%f K\n%f F"%(i+273,32+i*1.8),"K":"%f C\n%f F"%(i-273,i*1.8-459.4),"F":"%f C\n%f K"%(i/1.8-17.78,i/1.8+255.2)};print d[s[-1]]`

Questo è il mio primo tentativo su CodeGolf.


Benvenuti in PPCG. Questo è un bel tentativo per il primo golf! Ho aggiunto un po 'di zucchero al tuo post correggendo la formattazione e altro.
Ottimizzatore

2

Pyth, 126 byte

AYZczdJvY=Y*JK1.8
?%"%f F\n%f K",+32Y+J273.15qZ"C"?%"%f F\n%f C",-Y459.67-J273.15qZ"K"?%"%f C\n%f K",c-J32K*+J459.67c5 9qZ"F"

Mi sembra davvero lungo ... vabbè.


8
C'è una soluzione Python più corta di questa: P
orlp

@orlp Lo so, lo so ...
kirbyfan64sos

2

R, 150 144 141 byte

a=scan(,"");U=c("C","K","F");i=which(U==a[2]);Z=273.15;x=scan(t=a[1]);cat(paste(c(C<-c(x,x-Z,5*(x-32)/9)[i],C+Z,32+C*9/5)[-i],U[-i]),sep="\n")

Rientrato, con nuove linee:

a=scan(,"")
U=c("C","K","F")
i=which(U==a[2])
Z=273.15
x=as.double(a[1])
cat(paste(c(C<-c(x,x-Z,5*(x-32)/9)[i],C+Z,32+C*9/5)[-i],
            U[-i]),
    sep="\n")

Uso:

> a=scan(,"");U=c("C","K","F");i=which(U==a[2]);Z=273.15;x=scan(t=a[1]);cat(paste(c(C<-c(x,x-Z,5*(x-32)/9)[i],C+Z,32+C*9/5)[-i],U[-i]),sep="\n")
1: 23 C
3: 
Read 2 items
Read 1 item
296.15 K
73.4 F
> a=scan(,"");U=c("C","K","F");i=which(U==a[2]);Z=273.15;x=scan(t=a[1]);cat(paste(c(C<-c(x,x-Z,5*(x-32)/9)[i],C+Z,32+C*9/5)[-i],U[-i]),sep="\n")
1: 56.9999999 K
3: 
Read 2 items
Read 1 item
-216.1500001 C
-357.07000018 F
> a=scan(,"");U=c("C","K","F");i=which(U==a[2]);Z=273.15;x=scan(t=a[1]);cat(paste(c(C<-c(x,x-Z,5*(x-32)/9)[i],C+Z,32+C*9/5)[-i],U[-i]),sep="\n")
1: 86.987 F
3: 
Read 2 items
Read 1 item
30.5483333333333 C
303.698333333333 K

Grazie a @AlexA. & @MickyT. !


Bel lavoro. È possibile salvare un byte utilizzando as.double()anziché as.numeric().
Alex A.

Penso che la switchdichiarazione possa essere fatta con c(x,x-273.15,5*(x-32)/9)[i]4 personaggi
MickyT,

Grazie! In realtà, prima della versione 3.0, avrei potuto accorciarlo di più con as.real () invece di as.numeric (), ma ora la funzione non è più disponibile.
plannapus,

Un altro salvataggio sarebbe in sostituzione as.double(a[1])con scan(t=a[1]).
MickyT,

2

Javascript, 206 193 187 175 162 159 156

e=273.15,a=prompt(f=1.8).split(" "),b=+a[0],X=b-32,c=a[1];alert(c=="F"&&(X/f+"C\n"+(X/f+e+"K"))||(c=="C"?b*f+32+"‌​F\n"+(b+e+"K"):b*f-459.67+"F\n"+(b-e+"C")))

Grazie a Optimizer e Ismael Miguel per avermi aiutato a giocare un po 'più a lungo.


1
Puoi salvare alcuni byte convertendo if elsein?:
Optimizer

1
Potresti risparmiare un po 'di più unendo il tuo if ... return; return ?:areturn ?: ?:
Daniel

1
È possibile salvare 1 byte sostituendolo a=prompt().split(" "),e=273.15,f=1.8;alert([...]con a=prompt(e=273.15,f=1.8).split(" "),alert([...]. Inoltre, è possibile rimuovere gli spazi dopo l'unità. Inoltre, rimuovere returne spostare l' alertinterno della funzione si è ridotto molto! E invece di impostare a, basta usare il apply()metodo con la divisione. Ma qui si va: (function(b,c){alert(c=="F"&&((b-32)/f+"C\n"+((b-32)/f+e+"K"))||(c=="C"?b*f+32+"F\n"+(b+e+"K"):b*f-459.67+"F\n"+(b-e+"C")))}).apply(e=273.15,prompt(f=1.8).split(" "))! 166 byte ( -21 byte). Ping me in chat se hai dubbi.
Ismael Miguel,

1
L'ho appena portato a 162 comunque.
SuperJedi224,

1
Hai ragione, ho perso alcuni degli spazi. Grazie per averlo sottolineato.
SuperJedi224,

2

Mathematica, 66

Speriamo di correggere questa volta.

Print[1##]&@@@Reduce[F==1.8K-459.67&&C==K-273.15&&#==#2,,#2];&@@#&

Esempio

%[37 C]   (* % represents the function above *)

310.15 K

98.6 F


L'OP ha dichiarato in un commento che "Devi solo produrre gli altri due formati".
lirtosiast

@Thomas That e altri problemi (si spera) risolti. Non molto bene ma sto perdendo interesse.
Mr.Wizard,

1

Excel, 239 byte

=IF(RIGHT(A1,1)="C",LEFT(A1,LEN(A1)-2)+273.15&"K
"&9*LEFT(A1,LEN(A1)-2)/5+32&"F",IF(RIGHT(A1,1)="K",LEFT(A1,LEN(A1)-2)-273.15&"C
"&(LEFT(A1,LEN(A1)-2)*9/5-459.67&"F",(LEFT(A1,LEN(A1)-2)+459.67)*5/9&"K
"&(LEFT(A1,LEN(A1)-2)-32)*5/9&"C"))

112 byte dei quali vengono utilizzati per separare Valore e Unità. Qualcuno conosce una soluzione migliore?

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.