Czas mówienia po francusku

21

Bonjour, PPCG! Quelle heure est-il? Oznacza to, która godzina jest po francusku, bo właśnie o to chodzi w tym wyzwaniu.

Czas mówienia po francusku (przynajmniej formalnie) różni się nieco od mówienia po angielsku. Mówienie czasu zaczyna się od Il est (Jest). Następnie podajesz godzinę, po której następuje heures (godzina). (Jeśli nie znasz francuskich liczb, oto lista: http://blogs.transparent.com/french/french-numbers-learn-how-to-count-from-1-to-1000/ ). Jeśli jest godzina pierwsza, nie zastanawiaj się nad tym. Do południa używaj midi (bez heures), a do północy stosuj minuit .

O ile minutami nie jest 00, podążasz za nią wraz z liczbą minut. Istnieje jednak kilka wyjątków. Przez 15 minut chcesz powiedzieć et quart , a przez 30 minut chcesz powiedzieć et demi . Po 30 minutach zwiększysz liczbę godzin o jeden, a następnie dodasz słowo moins i 60 - minuty. Więc 18:40 jest Il sept heures moins vingt (vingt = 20). 45 minut to moins le quart .

Wreszcie, kończysz go porą dnia. Rano mówisz „ du matin” . Po południu (subiektywnie, ale zdefiniuję to jako od 13 do 17), mówisz de l'apres-midi (technicznie powinien być akcent nad e, ale eh). A na noc (17–12) mówisz „ du soir” . Pamiętaj, że do północy i południa ( minuit i midi ) nie umieszczasz żadnego z nich później - implikowana jest pora dnia, w zależności od tego, którego używasz.

Jak zapewne już ustaliłeś, wyzwaniem jest wydrukowanie bieżącego czasu lokalnego w języku francuskim przy użyciu tych reguł. Oto, jak powinien wyglądać przykładowy wydruk w różnych porach. (Czas w nawiasach nie musi być oczywiście drukowany, jest tylko tam, więc wiesz, jakie są godziny):

Il est sept heures du matin. (7:00 A.M)
Il est deux heures de l'apres-midi. (2:00 P.M)
Il est une heure du matin. (1:00 A.M)
Il est huit heures du soir. (8:00 P.M)
Il est midi. (12:00 P.M, Noon)
Il est minuit. (12:00 A.M, Midnight)
Il est cinq heures vingt du soir. (5:20 P.M)
Il est six heures et quart du matin. (6:15 A.M)
Il est neuf heures et demi du matin. (9:30 A.M)
Il est quatre heures moins dix de l'apres-midi. (3:50 P.M, not 4:50!)
Il est midi moins le quart. (11:45 A.M)

To jest golf golfowy, więc wygrywa najkrótszy kod. Powodzenia!

EDYCJA: okres jest wymagany.

spaghetto
źródło
2
Powiązane: Przeliteruj liczby w języku francuskim
NinjaBearMonkey
Jaka powinna być wydajność na przykład na 08:41? Il est huit heures quarante et une du matin(poprawnie) czy Il est neuf heures moins dix-neuf du matin(brzmi dziwnie)?
Blackhole,
Czy powinniśmy koniecznie przedstawić wynik, czy możemy go po prostu zwrócić? Czy dozwolone są funkcje wewnętrzne, które konwertują liczby na liczby?
Blackhole,
Czy powinniśmy dodać akcent après-midi? Czy możemy?
Blackhole,
Jeśli chcesz. To nie jest konieczne.
spaghetto

Odpowiedzi:

4

PHP - 521 473 bajtów

Dodałem kilka nowych linii dla czytelności:

$w=split(A,'AuneAdeuxAtroisAquatreAcinqAsixAseptAhuitAneufAdixAonzeAdouzeAtreizeA
quatorzeAAseizeAdix-septAdix-huitAdix-neufAvingtAvingt et une');$h=idate('H');if(
$r=($m=idate('i'))>30){$h=++$h%24;$m=60-$m;}echo'Il est '.($h?$h==12?midi:$w[$h%12]
.' heure'.($h%12<2?'':s):minuit).($r?' moins':'').($m==15?($r?' le ':' et ').quart
:($m==30?' et demi':($m?' '.($m<22?$w[$m]:"$w[20]-".$w[$m%10]):''))).($h%12?($h-=$r
)<12?' du matin':($h<17?" de l'après-midi":' du soir'):'').'.';

Metoda używana do konwersji liczby na liczbę w języku francuskim jest zainspirowana tą odpowiedzią na inny wyzwanie przez edc65 .

Oto wersja bez golfa:

/** Define numerals **/
$numerals = [
    '', 'une', 'deux', 'trois', 'quatre',
    'cinq', 'six', 'sept', 'huit', 'neuf',
    'dix', 'onze', 'douze', 'treize', 'quatorze',
    '', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf',
    'vingt', 'vingt et une'
];

/** Get current time **/
$hours = idate('H');
$minutes = idate('i');

/** Check if we need to count in reverse **/
$reverse = $minutes > 30;
if ($reverse) {
    $hours = ($hours + 1) % 24;
    $minutes = 60 - $minutes;
}

echo 'Il est ';

/** Print hours **/
if ($hours === 12) {
    echo 'midi';
}
else if ($hours === 0) {
    echo 'minuit';
}
else
{
    echo $numerals[$hours % 12] .' heure';
    if ($hours % 12 !== 1) {
        echo 's';
    }
}

/** Print minutes **/
if ($reverse) {
    echo ' moins';
}

if ($minutes === 15)
{
    if ($reverse) {
        echo ' le ';
    }
    else {
        echo ' et ';
    }

    echo 'quart';
}
else if ($minutes === 30) {
    echo ' et demi';
}
else if ($minutes !== 0)
{
    echo ' ';

    if ($minutes < 22) {
        echo $numerals[$minutes];
    }
    else {
        echo $numerals[20] .'-'. $numerals[$minutes % 10];
    }
}

/** Print daytime **/
if ($hours % 12 !== 0)
{
    if ($reverse) {
        --$hours;
    }

    if ($hours < 12) {
        echo ' du matin';
    }
    else if ($hours < 17) {
        echo " de l'après-midi";
    }
    else {
        echo ' du soir';
    }
}

echo '.';
Czarna dziura
źródło
4

Python 3, 586 547 556 506 505 502 498 497 493 bajtów

Moja pierwsza próba gry w golfa. Naprawdę nie jestem pewien, jaki sposób wybiorę, zwłaszcza nlistę. Ale chciałem spróbować.

from datetime import*;t=datetime.now()
n='/une/deux/trois/quatre/cinq/six/sept/huit/neuf/dix/onze/douze/treize/quatorze/et quart/seize/dix-sept/dix-huit/dix-neuf/vingt//et demi'.split('/')
n[21:22]=['vingt-'+i for i in['et-une']+n[2:10]]
h,m=t.hour,t.minute;s=h//12;h%=12
e=' d'+('u matin',("e l'après-midi","u soir")[h>4])[s]
try:m=' '[:m]+n[m]
except:m=' moins '+(n[60-m],'le quart')[m==45];h+=1
e,h=('',e,('minuit','midi')[h//12^s],n[h]+' heures'[:h+5])[h%12>0::2]
print('Il est',h+m+e+'.')

Nie golfowany:

from datetime import datetime

time = datetime.now()
numbers = [
    '', 'une', 'deux', 'trois', 'quatre',
    'cinq', 'six', 'sept', 'huit', 'neuf',
    'dix', 'onze', 'douze', 'treize', 'quatorze',
    'et quart', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf',
    'vingt', 'vingt-et-une', 'vingt-deux', 'vingt-trois', 'vingt-quatre',
    'vingt-cinq', 'vingt-six', 'vingt-sept', 'vingt-huit', 'vingt-neuf',
    'et demi']

status, hour = divmod(time.hour, 12)
if status:
    ending = " du soir" if h>4 else " de l’après-midi"
else:
    ending = " du matin"

try:
    if not time.minute:
        minutes = ""
    else:
        minutes = " " + numbers[time.minute]
except IndexError:
    hour += 1
    if time.minute == 45:
        minutes = " moins le quart"
    else:
        minutes = " moins " + numbers[60 - time.minute]

if hour%12:    # 'whole' hours
    hours = numbers[hour] + " heures"
    if hour == 1:
        # removing extra 's'
        hours = hours[:-1]
else:          # midnight or noon
    ending = ""
    if (hour == 12 and status) or (hour == 0 and status == 0):
        hours = "minuit"
    else:
        hours = "midi"

print('Il est', hours + minutes + ending + '.')
409_Konflikt
źródło
2
Za pomocą można zapisać około 50 bajtów 'minuit#une#deux#...#vingt-neuf#et demi'.split('#'). Może być jeszcze krótszy, aby po prostu jakoś skompresować strunę.
Martin Ender
@Martin tak, właśnie widziałem to również w odpowiedzi Blackhole. Chciałem jednak spróbować go skrócić, używając powtórzeń związanych z „vingt-xxx”. Ale po pewnym czasie snu, odkąd Il est deux heures moins trois du matin.
409_Conflict
@MathiasEttinger kilka poprawek, zamiast vingt masz „voingt”, a 21 to „vingt et un”, a nie „vingt-et-une”
Brian Tuck
1
Dzięki za vingt . Powinno być na 21 vingt-et-une, ponieważ minuta jest kobieca, w ten sam sposób, w jaki 01:01 jest najgorętszym momentem.
409_Conflict
@BrianTuck Także 21 jest vingt-et-un lub vingt-et-une od 1990 zamiast vingt et un or vingt et une : fr.wiktionary.org/wiki/vingt_et_une
409_Conflict
3

JavaScript (ES6), 506 495 bajtów

Edycja: skompresowany w acelu zaoszczędzenia kilku bajtów.

a=`
un
j
k
yre
h
six
w
v
p}
onldoultreilyorl
seize}-w}-v}-p~~ et un{j{k{yre{h{six{w{v{p
et demi`,[...`hjklpvwy{}~`].map((x,w)=>a=a.split(x).join(`cinq|deux|trois|ze
|neuf|huit|sept|quat|~-|
dix|
vingt`.split`|`[w])),a=a.split`
`,alert(`Il est ${(e=(d=((b=(z=new Date).getHours())+(y=(c=z.getMinutes())>30))%24)%12)?a[e]+` heure${e-1?"s":""}`:d?'midi':'minuit'} ${y?"moins ":""}${y?c-45?a[60-c]:'le quart':c-15?a[c]:'et quart'}${e?[' du matin'," de l'apres-midi",' du soir'][(b>12)+(b>16)]:""}.`)

Wyjaśnienie:

a = 'compressed string of french numbers with 'et demi' for 30 and 15 removed';
a = // code that decompresses a

// a,b,c,d,e,y,z are all inlined into the first expression that uses them
z = new Date();
b = z.getHours();
c = z.getMinutes();
y = c > 30; // true if 60 - minutes, false otherwise
d = (b + y) % 24; // the next hour if y
e = d % 12; // is it not noon and not midnight?

alert(
    "Il est " +
    // add the hour
    // if d is not 0 or 12, add d + 'heure(s)'
    (e ? a[e] + ` heure${e-1?"s":""}` : d ? 'midi' : 'minuit') +
    " " +
    (y ? "moins " : "") + // add 'moins' if necessary

    ( // add the minute
      y? // necessary to subtract from 60?
        c-45?
          a[60-c] // add normal number word
          :'le quart' // handle special case for 45
        :c-15?
          a[c] // add normal word
          :'et quart' // handle special case for 15
    ) +
    ( // select appropriate ending
      e? // is it not noon and not midnight?
        // create array of endings
        [" du matin"," de l'apres-midi"," du soir"]
          // selects item 0 if b in [0, 12], item 1 if b in [13, 16] and item 2 if b > 16
          [(b > 12) + (b > 16)]
        :"" // if it's noon or midnight, no ending is necessary
    ) +
    "." // add period
)
DankMemes
źródło
2

C 860 835 794 bajtów

Absolutnie przerażające, ale prawdopodobnie mogą być jeszcze krótsze. Na tej stronie dodano wiele nowych linii do celów formatowania. Rzeczywisty kod źródłowy ma znaki nowej linii po #include i #defines, ale wszystko, począwszy od char * do ostatniego w („. \ N”);}, wszystko w jednym wierszu. Skróciłem go, usuwając wartości z 22, ..., 29 w tablicy ciągów, zamiast tego ponownie wykorzystując ciągi dla 2, ..., 9 i przygotowując "vingt-", gdy jest to właściwe. (Naprawdę mam nadzieję, że nie wprowadziłem błędu!)

#include <sys/time.h>
#define w printf
#define q tm_min
#define r tm_hour
char*a[]={"minuit","une","deux","trois","quatre","cinq","six","sept","huit","neuf","dix",
"onze","douze","treize","quatorze","quart","seize","dix-sept","dix-huit","dix-
neuf","vingt","vingt-et-une",0,0,0,0,0,0,0,0,"demi"};
h=1,s=1,m,e,l,t,p,o,v;struct tm j;
main(){struct timeval i;gettimeofday(&i,0);localtime_r(&i.tv_sec,&j);
j.q>30?m=1,++j.r,j.q=60-j.q:j.q==15||j.q==30?e=1:0;j.q>21&&j.q<30?v=1:0;
j.r%12?j.r<12?t=1:j.r-m<17?p=1:(o=1):0;
j.q==15&&m?l=1:0;j.r%12?j.r%12==1?s=0:0:(h=0,s=0);
w("Il est ");j.r==12?w("midi"):w("%s",a[j.r%12]);h?w(" heure"):0;s?w("s"):0;
m?w(" moins"):0;e?w(" et"):0;l?w(" le"):0;
j.q?v?w(" vingt-"):w(" "),w("%s",a[j.q-20*v]):0;
t?w(" du matin"):p?w(" de l'apres-midi"):o?w(" du soir"):0;w(".\n");}

Lubię to:

#include <sys/time.h>
#define w printf
#define q tm_min
#define r tm_hour
char*a[]={"minuit","une","deux","trois","quatre","cinq","six","sept","huit","neuf","dix","onze","douze","treize","quatorze","quart","seize","dix-sept","dix-huit","dix-neuf","vingt","vingt-et-une",0,0,0,0,0,0,0,0,"demi"};h=1,s=1,m,e,l,t,p,o,v;struct tm j;main(){struct timeval i;gettimeofday(&i,0);localtime_r(&i.tv_sec,&j);j.q>30?m=1,++j.r,j.q=60-j.q:j.q==15||j.q==30?e=1:0;j.q>21&&j.q<30?v=1:0;j.r%12?j.r<12?t=1:j.r-m<17?p=1:(o=1):0;j.q==15&&m?l=1:0;j.r%12?j.r%12==1?s=0:0:(h=0,s=0);w("Il est ");j.r==12?w("midi"):w("%s",a[j.r%12]);h?w(" heure"):0;s?w("s"):0;m?w(" moins"):0;e?w(" et"):0;l?w(" le"):0;j.q?v?w(" vingt-"):w(" "),w("%s",a[j.q-20*v]):0;t?w(" du matin"):p?w(" de l'apres-midi"):o?w(" du soir"):0;w(".\n");}

Wersja bez golfa, bez „optymalizacji przestrzeni” (również dość brzydka):

#include <stdio.h>
#include <string.h>
#include <time.h>

#include <sys/time.h>

int main(int argc, char *argv[])
{
        struct timeval tv;
        struct tm local_time;
        char *nums[] = {"minuit", "une", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quart", "seize", "dix-sept", "dix-huit", "dix-neuf", "vingt", "vingt-et-une", "vingt-deux", "vingt-trois", "vingt-quatre", "vingt-cinq", "vingt-six", "vingt-sept", "vingt-huit", "vingt-neuf", "demi"};
        int heure = 1;
        int s = 1;
        int moins = 0;
        int et = 0;
        int le = 0;
        int matin = 0, aprem = 0, soir = 0;

        memset(&local_time, 0, sizeof local_time);
        gettimeofday(&tv, NULL);
        localtime_r(&tv.tv_sec, &local_time);

#if 0
        local_time.tm_min = atoi(argv[1]);
        local_time.tm_hour = atoi(argv[2]);
#endif
        if (local_time.tm_min > 30) {
                moins = 1;
                local_time.tm_hour += 1;
                local_time.tm_min = 60 - local_time.tm_min;
        } else if (local_time.tm_min == 15 || local_time.tm_min == 30) {
                et = 1;
        }

        if (local_time.tm_hour % 12) {
                if (local_time.tm_hour < 12)
                        matin = 1;
                else if (local_time.tm_hour < 17)
                        aprem = 1;
                else if (local_time.tm_hour == 17 && moins)
                        aprem = 1;
                else
                        soir = 1;
        }

        if (local_time.tm_min == 15 && moins)
                le = 1;

        if (local_time.tm_hour % 12 == 0) {
                heure = 0;
                s = 0;
        } else if (local_time.tm_hour % 12 == 1) {
                s = 0;
        }

        printf("Il est ");

        if (local_time.tm_hour == 12)
                printf("midi");
        else
                printf("%s", nums[local_time.tm_hour % 12]);

        if (heure)
                printf(" heure");

        if (s)
                printf("s");

        if (moins)
                printf(" moins");

        if (et)
                printf(" et");

        if (le)
                printf(" le");

        if (local_time.tm_min)
                printf(" %s", nums[local_time.tm_min]);

        if (matin)
                printf(" du matin");
        else if (aprem)
                printf(" de l'apres-midi");
        else if (soir)
                printf(" du soir");

        printf(".\n");
        return 0;
}

(Funkcja #if 0 była przeznaczona tylko do testowania różnych wartości czasu za pomocą wiersza poleceń).

Tob Ernack
źródło
1
Rekwizyty do próby odpowiedzi C :) Spójrz na dobrą stronę - prawdopodobnie jest krótsza niż w Javie!
spaghetto