Traduzir números para francês

46

Os franceses soletram números de uma maneira peculiar.

  • 1-16 são "normais"
  • 17-19 são escritos 10 + 7. 10 + 8, 10 + 9 .
  • 20-69 são "normais" (OK, OK! Na verdade, mas eles estão nesse desafio)
  • 70-79 são 60 + 10, 60 + 11 ... 60 + 10 + 7, 60 + 10 + 8, 60 + 10 + 9 .
  • 80-99 são 4 * 20, 4 * 20 + 1, 4 * 20 + 2 ... 4 * 20 + 16, 4 * 20 + 10 + 7, 4 * 20 + 10 + 8, 4 * 20 + 10 + 9

Desafio:

Pegue um número inteiro positivo no intervalo [1.100] e faça a saída do modo "francês". Você deve saída lo exatamente como é mostrado abaixo, com *e +, por isso, 97é 4*20+10+7, não [4 20 10 7]ou qualquer outra coisa.

Casos de teste:

1  - 1
.. - ..
16 - 16
17 - 10+7
18 - 10+8
19 - 10+9
20 - 20
21 - 21
.. - ..
69 - 69
70 - 60+10
71 - 60+11
72 - 60+12
77 - 60+10+7
78 - 60+10+8
79 - 60+10+9
80 - 4*20
81 - 4*20+1
82 - 4*20+2
.. - ..
90 - 4*20+10
91 - 4*20+11
96 - 4*20+16
97 - 4*20+10+7
98 - 4*20+10+8
99 - 4*20+10+9
100 - 100
Stewie Griffin
fonte
14
Todo idioma que eu conheço tem uma transição nos "adolescentes", como o de cima 16para 10+7cima. (Em inglês, isso acontece entre 12e 10+3, com um pouco mais de disfarce morfológico.) Eu sempre fui um pouco superestimada com o fato de que diferentes idiomas fazem essa transição em números diferentes.
Greg Martin
25
Por que deveria ser "vingt-deux" 22quando "dix-huit" é 10+8?
Titus
11
Felizmente, este é um site de quebra-cabeças de programação e não um site de curiosidades linguísticas. Caso contrário, as pessoas podem ficar irritadas quando o OP comete erros tolos. Ufa!
Stewie Griffin
4
@StewieGriffin As pessoas ainda ficaram irritadas.
Freira vazada
2
Como francês, acho isso muito bom: D.
Walfrat 27/04

Respostas:

13

Excel, 153 149 bytes

=IF(OR(A1<17,A1>99,AND(A1>19,A1<70)),A1,IF(A1<20,"10+"&A1-10,IF(A1<80,"60","4*20")&IF(A1=80,,IF(MOD(A1,20)>16,"+10+"&MOD(A1,20)-10,"+"&MOD(A1,20)))))

Tenho certeza de que isso poderia ser melhor, lutei para encontrar uma maneira eficiente de explicar a # 80.

editar: consolidou os casos 'normais' para economizar 4 bytes. # 80 ainda é uma merda.

Não foi possível encontrar uma resposta específica aqui, não tenho certeza das regras do code-golf tbh. Posso usar várias células no Excel e adicionar a contagem de bytes de cada uma?

ie Para uma entrada na célula A1

A2: 11 bytes

=MOD(A1,20)

A3 (resultado): 125 bytes

=IF(OR(A1<17,A1>99,AND(A1>19,A1<70)),A1,IF(A1<20,"10+"&A1-10,IF(A1<80,"60","4*20")&IF(A1=80,,IF(A2>16,"+10+"&A2-10,"+"&A2))))

Para um total de 136?

qoou
fonte
Eu acho que deveria ser permitido escrever código em várias células. IMHO é como ter variáveis ​​ou funções intermediárias em outras linguagens de programação.
Pajonk
Eu sinto que deve haver alguma penalidade no uso de várias células, assim como existe uma penalidade no uso de funções em outros idiomas (o de digitar o clichê para declarar a função). Talvez o teste tenha suporte para codificação (ou seja, CSV), portanto, o número necessário de vírgulas e (se necessário) aspas?
Muzer #
Não conheço nenhum formato no qual os arquivos do Excel possam ser salvos com uma saída reconhecível. Os arquivos CSV, por padrão, não suportam funções como essas e interromperão qualquer função que use vírgula. Se salvo como texto puro em uma coluna com uma nova linha entre células, ele poderá ser copiado diretamente no Excel e na função. Nesse caso, 1 byte seria adicionado para cada célula adicional.
qoou
Salve um byte convertendo IF(A1=80,,IF(MOD(A1,20)>16,"+10+"&MOD(A1,20)-10,"+"&MOD(A1,20)))paraIFS(A1=80,,MOD(A1,20)>16,"+10+"&MOD(A1,20)-10,1,"+"&MOD(A1,20))
Greedo 28/04
No Libreoffice calc, você pode pular )o final, pode fazer o mesmo no Excel? Assim, você pode salvar 5 "bytes" (realmente existem UCS2-Chars, portanto, se você disser Byte == octeto, deve contar em dobro). E você deve alterar a ,em;
12431234123412341234123
8

Retina , 52 48 bytes

4 bytes salvos graças a Neil

^7\B
60+1
^9\B
81
^8\B
4*20+
1(?=7|8|9)
10+
\+0

Experimente online! ou verifique todas as entradas (fornecidas por Neil)

Explicação

^7\B
60+1
^9\B
81
^8\B
4*20+

Primeiro, lidamos com a tradução de 70, 80 e 90. Nesses três primeiros estágios, um 7 no início com outro caractere a seguir é substituído por 60+1. Da mesma forma, 9é substituído por 81e 8por 4*20+1. A substituição de 9é essencialmente alterá-lo para "oitenta e dez" e tal, para que o 8item seja tratado pela próxima substituição, que economiza bytes ao escrever 4*20+1duas vezes.

1(?=7|8|9)
10+

Isso lida com os casos de 17, 18e 19substituindo o 1em cada um por 10+.

\+0

Finalmente, nunca deve haver um +0no final, então exclua-o se estiver lá.

Gato de negócios
fonte
Certamente em vez se behinds olhar e lookaheads você pode usar grupos de captura
Downgoat
Não funciona 7-9, mas acho que você não precisa olhar para trás: experimente online!
26517 Neil
@ Neil eu percebi que enquanto eu estava fora: P Mas obrigado pela nova versão!
Cat Business
@Downgoat Eu poderia substituir o lookahead por um grupo de captura, mas ele não salvaria nenhum bytes, pois $1é tão longo quanto ?=.
Business Cat
7

JavaScript (ES6), 73 71 bytes

f=n=>n>16&n<20?'10+'+n%10:n<70|n>99?n:n%20?f(n-n%20)+'+'+f(n%20):'4*20'

Versão bônus que imprime os números à medida que são escritos na verdade por mais 2 bytes:

f=n=>n<17|n>99?n:n<20?'10+'+n%10:n%20?f(n-n%20)+'+'+f(n%20):n-80?n:'4*20'
ETHproductions
fonte
1
falha em muitas entradas; na verdade, só funciona para 1..20, 30, 40, 50, 60, 80 e 100.
Titus
@ Titus Eu acho que você está entendendo mal a maioria das saídas. 23, por exemplo, deve produzir 23, não 20+3.
ETHproductions
Salve dois bytes com(m=n%20)
Titus
@ Titus Obrigado, mas eu já tentei isso, e não funciona em 70-99 porque mé redefinido 0na f(n-n%20)chamada. (É uma variável global)
ETHproductions
Você pode salvar um byte, alterando n<70|n>99para n%100<70. Além disso, você poderia adicionar um compilador de teste?
Kevin Cruijssen
5

R, 110 bytes

i=scan()
r=i%%10;paste0(ifelse(i>16&i<20,"10+",ifelse(i>69&i<80,"60+10+",ifelse(i>16&i<20,"4*20+",i-r/10))),r)
Neil
fonte
Tente em (i-r)/10vez de floor(i/10). E i>15deveria ser i>16.
Titus
5

PHP, 99 bytes (eu quero ser a versão feliz)

uma porta reta de JS da ETHproductions , 4 bytes de golfe. Imprime os números conforme solicitado pelo OP.

function f($n){return$n<17|$n>19?$n>60&$n<100?($m=$n%20)?f($n-$m)."+".f($m):'4*20':$n:"10+".$n%10;}

demolir

function f($n){return
    $n<17|$n>19
        ?$n>69&$n<100
            ?($m=$n%20)
                ?f($n-$m)."+".f($m) # 70..79, 81..99
                :'4*20'             # 80
            :$n                     # 1..16, 20..69
        :"10+".$n%10                # 17..19
    ;
}

Quero a versão correta, 114 98 bytes

nova abordagem inspirada na ETHproductions , imprime os números à medida que são detalhados.

function f($n){return$n>16&$n<100?$n-80?($m=$n%($n>60?20:10))?f($n-$m)."+".f($m):$n-$m:'4*20':$n;}

experimente online .

demolir

function f($n){return
    $n>16&$n<100
        ?$n-80
            ?($m=$n%($n>60?20:10))
                ?f($n-$m)."+".f($m) # $n%$m>0
                :$n-$m              # 10,20,30,40,50,60
            :'4*20'                 # 80
        :$n                         # 1..16, 100
;}
Titus
fonte
4

Python 2, 130 108 bytes

22 bytes salvos graças a @mathjunkie

f=lambda x:79<x<100and('4*20'+('+'+f(x-80))*(x>80))or 69<x<100and'60+'+f(x-60)or 16<x<20and'10+'+`x-10`or`x`

Experimente online!

Uriel
fonte
108 bytes: TIO
math junkie
1
Você precisa contar f=porque o usou dentro do lambda.
Leaky Nun
@LeakyNun corrigido
Uriel
3

Lote, 220 217 bytes

@set/pn=
@set s=
@if %n% gtr 99 goto g
@if %n% gtr 79 set s=+4*20&set/an-=80
@if %n% gtr 69 set s=+60&set/an-=60
@if %n% gtr 16 if %n% lss 20 set s=%s%+10&set/an-=10
:g
@if %n% gtr 0 set s=%s%+%n%
@echo %s:~1%

Recebe entrada em STDIN. Gerar e remover os principais +economiza 1 byte sobre o invólucro especial 80. Edit: Salvo 3 bytes graças ao @ ConorO'Brien.

Neil
fonte
Você pode salvar 3 bytes através da remoção @echo offe prefixar todas as declarações exceto para instrução de loop hte com@
Conor O'Brien
@ ConorO'Brien Huh, eu me pergunto por que eu esqueci de fazer isso desta vez ...
Neil
2

Geléia , 55 bytes

⁹
’,ṃ60Ṁ€
⁹%80“4*20”,
Dj⁾0+µ¹e?“×ØŒ‘
%ȷ2:“FP‘S‘ŀḟ0Ç€j”+

Experimente online! ou veja uma suíte de testes

Sem dúvida, há um caminho mais curto!

Quão?

+ - Link 1, helper for 1-69&100: number s=0, number n
⁹ - link's right argument, n

’,ṃ60Ṁ€ - Link 2, helper for 70-79: number s=1, number n
’       - decrement s -> 0
 ,      - pair -> [0,n]
  ṃ60   - base decompress (vectorises) using [1,2,...60]  effectively -> [60,[1,n%60]]
     Ṁ€ - maximum for €ach effectively -> [60,n%60]

⁹%80“4*20”, - Link 3, helper for 80-99: number s=2, number n
⁹           - link's right argument, n
 %80        - mod 80
    “4*20”  - literal ['4','*','2','0']
          , - pair -> [['4','*','2','0'],n]

Dj⁾0+µ¹e?“×ØŒ‘ - Link 4, reformat 17-19: element v (may be char list or number)
        ?      - if
       e       - v exists in
         “×ØŒ‘ - literal [17,18,19]
               - then:
D              -   convert to decimal list  e.g. [1,7]
  ⁾0+          -   literal ['0','+']
 j             -   join                          [1,'0','+',7]
     µ         - else:
      ¹        -   identity, v

%ȷ2:“FP‘S‘ŀḟ0Ç€j”+ - Main link: number n in [1,100]
 ȷ2                - literal 100
%                  - mod (convert 100 to 0)
    “FP‘           - literal [70,80]
   :               - integer division (vectorises)
        S          - sum (0 for 1-69&100; 1 for 70-79; 2 for 80-99)
         ‘         - increment (...1, 2 or 3)
          ŀ        - call link at index (1, 2 or 3) as a dyad(sum, n)
           ḟ0      - filter out zeros (remove 0 from 4*20+0)
             ǀ    - call the last link (4) as a monad for each
                ”+ - literal '+'
               j   - join
Jonathan Allan
fonte
2

Pitão, 61 56 bytes

L?}b}17 19++T\+eb|bk?}/QTr6T.s+?<Q80"60+""4*20+"y%Q20\+y

Teste online!

Agradecemos a Leaky Nun por uma melhoria de 5 bytes!

Explicação:

                     | Implicit: Q=eval(input())
L                    | Define y(b):
 ?}b}17 19           |  If b is in the inclusive range from 17 to 19:
          ++T\+eb    |   Return "10+" + (last digit of b)
                 |b  |  Else: if b!=0: return b
                   k |   Else: return an empty string (Leaves a trailing '+' for case 80)
_____________________|________________
?}/QTr6T                              | If 70<=Q<100:
          +                           |  Concatenate the next two expressions:
           ?<Q80                      |   If Q<80:
                "60+"                 |    Evaluate to "60+"
                     "4*20+"          |    Else: Evaluate to "4*20+"
                            y%Q20     |   y(Q%20)
        .s                       \+   |  Strip off trailing '+', if present (for case 80)
                                   y  | Else: return y(Q)
                                   (Q)| Trailing Q is implicitly added
K Zhang
fonte
*-Q100>Q69→ #}/QTr6T
Leaky Nun
@]b}17 19→ #}b}17 19
Leaky Nun
+"10+"eb→ #j\+,Teb
Leaky Nun
@LeakyNun Obrigado pela ajuda com o golfe! Fiz as alterações que você sugeriu.
K Zhang
1

Python3, 127 bytes

m,r=map,range;l=[*r(1,17),*m("10+{}".format,(7,8,9))];f=[0,*l,*r(20,61),*m("60+{}".format,l),"4*20",*m("4*20+{}".format,l),100]

Cada elemento da matriz contém sua representação:

for i in range(1,101):
    print(i, f[i])

Na verdade, o código não cria uma função, apenas uma matriz - não sei se isso é permitido. Caso contrário, eu teria que fazer isso 139 bytes adicionando f=[...].__getitem__.

emu
fonte
Bem-vindo ao PPCG! Eu acredito que houve uma discussão sobre meta sobre o envio de matrizes como mapeamentos de inteiros a objetos, mas eu não consigo encontrá-lo no momento. Vou informá-lo se sim (e qual foi o resultado dessa discussão). De qualquer forma, você não precisará f=, porque funções não nomeadas (ou seja, expressões que são avaliadas para a função enviada) são boas, a menos que o nome seja necessário para algo como recursão.
Martin Ender
Não há um consenso claro, mas a resposta votada marginalmente sugere que você permita sua solução.
Martin Ender
0

Java 7, 97 96 109 bytes

String c(int i){return i>16&i<20?"10+"+(i-10):i%100<70?i+"":i<80?"60+"+c(i-60):"4*20"+(i<81?"":"+"+c(i-80));}

+13 bytes para o caso de correção de erros 80.. :(

Explicação:

String c(int i){      // Method with integer parameter and String return-type
  return i>16&i<20?   //  If 17..19:
    "10+"+(i-10)      //   Return "10+" + `i`-10
   :i%100<70?         //  Else if 1..16; 20..69; 100:
    i+""              //   Return `i`
   :i<80?             //  Else if 70..79:
    "60+"+c(i-60)     //   Return "60+" + recursive-call with `i`-60
   :                  //  Else (80..99):
    "4*20"+           //   Return "4*20" +
     (i<81?           //   If 80:
      ""              //    nothing
     :                //   Else (81..99)
      "+"+c(i-80));   //    recursive-call with `i`-80
}                     // End of method

Código do teste:

Experimente aqui.

class M{
  static String c(int i){return i>16&i<20?"10+"+(i-10):i%100<70?i+"":i<80?"60+"+c(i-60):"4*20"+(i<81?"":"+"+c(i-80));}

  public static void main(String[] a){
    for (int i = 1; i <= 100; i++) {
      System.out.println(c(i));
    }
  }
}
Kevin Cruijssen
fonte