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

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?


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á.


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'

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)

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
;}

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!


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.


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

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

*-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__.


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));
    }
  }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.