Bir Tarihi Basitleştirin


9

Bu, kesirleri basitleştirmeye benzer, ancak Tarihler!

Programınızın girişi şu biçimde olmalıdır mm/dd : Örneğin

3/4 //March 4
12/15 //December 15
1/1 // January 1

Girdinin, aylarda bu sayıda gün olacak şekilde geçerli olacağını varsayıyoruz:

January 31
February 28
March 31
April 30
May 31
June 30
July 31
August 31
September 30
October 31
November 30
December 31

Programınızın işi varsayılan geçerli girdiyi almak ve yinelemeli olarak (veya yinelemeli olarak) tarihi basitleştirmek ve her yinelemede (0 dahil) tarihi yukarıda yazılan ayın tam adıyla çıktı olarak almaktır.

Örneğin:

Bir girdi verildiğinde:

12/18

Çıktı

December 18
June 9
February 3

Önceden basitleştirilmiş bir girdi yalnızca kendi çıktısını verir:

11/17

Çıktılar:

November 17

Ay isimleri sizin dilinizdeki bir fonksiyondan gelemez. Dizeler gizlenebilir, hesaplanabilir, ancak istediğiniz gibi olabilir, ancak GetMonthString (4) veya başka bir şey gibi standart bir işlevi kullanamazsınız, ya bu işlevi yazmanız ya da ay adlarını açıklandığı gibi çıkarmanın bir yolunu bulmanız gerekir.

Basitleştirilmiş tarihin yasadışı bir tarih oluşturduğu durumları düşünemiyorum, ancak yol boyunca yasadışı bir tarih çıkarırsanız, çıktı:

Illegal Date

Ancak bunun gerçekleşemeyeceğinden eminseniz, bu durumu kapsayan bir kodunuzun olması gerekmez. Çıkarılan tarihlerin her zaman yukarıda açıklananlara göre geçerli olması gerekir (ayların ve günlerin 1'den başladığını söylemeye gerek yoktur).

Algoritma:

Her yinelemede, pay ve paydayı bölen en küçük sayıya bölünürsünüz.

Yani, tüm sayıları bulursunuz, hem pay hem de paydayı bu sayıya bölmek, her ikisi de tamsayı olan (ortak faktörler) yeni bir pay ve payda üretir. En küçük olanı seçin ve yeni bir kesir oluşturmak için pay ve paydayı ayrı ayrı bölün. Bölebileceğiniz tek sayı 1 ise, olabildiğince basitleştirdiniz ve durdunuz.

Umarım açık olmuştur.

Herhangi bir dile izin verilir. Bu Code Golf, en kısa kod kazanıyor!


Ben bir cevap gönderirken soru kapatıldı. Doh!
t-clausen.dk

@ t-clausen.dk Meydan okuma yeniden açıldı.
AdmBorkBork

Neden gelen 12/18etmek 6/9değil, 4/6(ben immedialtely var bir kısmını çıkan basitleştirilmiş değeri basitleştirmek zaman ... tüm yineleme karmaşa alamadım)?
edc65

Yanıtlar:


2

Jöle , 59 bayt

ṣ”/VµÆDf/2ị:@µÐĿị1¦€“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»ṣ⁶¤j€⁶j⁷

Çevrimiçi deneyin!

Nasıl çalışır

ṣ”/VµÆDf/2ị:@µÐĿị1¦€“...»ṣ⁶¤j€⁶j⁷  Main link. Argument: mm/dd

ṣ”/                                Split at slashes.
   V                               Eval each chunk, yielding [m, d] (integers).
    µ                              Begin a new, monadic chain. Argument: [m, d]
             µÐĿ                   Execute the chain to the left until the results
                                   are no longer unique. Yield the list of all
                                   intermediate results.
     ÆD                              Compute the divisors of each number.
       f/                            Intersect them.
         2ị                          Select the one at index 2. If there is only
                                     one divisor, ị wraps around and selects 1.
           :@                        Divide [m, d] by this common divisor.
                        ¤            Combine the links to the left into a chain.
                 “...»                 Yield the month's name, space-separated.
                      ṣ⁶               Split at spaces.
                €                    For each pair...
             ị                          index into the month's names...
              1¦                        for the first element.
                         j⁶€         Join each pair, separating by spaces.
                            j⁷       Join, separating by linefeeds.


0

TSQL 296 bayt

Standart veri adını kullanmama izin verilmiyor, bayt çok pahalıya mal oldu, ancak birkaç bayt kaydetmek için varsayılan tarih açıklamasının ilk 3 karakterini kullandım (mon dd yyyy hh: miAM (veya PM) biçiminde) ve ay adının geri kalanı.

golfed:

use master
DECLARE @ varchar(5) = '12/2'

DECLARE @m int=month('2000/'+@),@d INT=day('2000/'+@)WHILE @m>0BEGIN PRINT left(dateadd(d,@m*29,0),3)+choose(@m,'uary','uary','ch','il','','e','y','ust','tember','ober','ember','ember')+' '+LEFT(@d,2)SELECT @m/=min(n),@d/=min(n)FROM(SELECT number FROM spt_values)x(n)WHERE @m%n+@d%n=0 and n>1 END

Çevrimiçi deneyin

Ungolfed:

use master
DECLARE @ varchar(5) = '12/2'

DECLARE @m int=month('2000/'+@),@d INT=day('2000/'+@)
WHILE @m>0
BEGIN
PRINT
 left(dateadd(d,@m*29,0),3)
 +choose(@m,'uary','uary','ch','il','','e','y','ust',
  'tember','ober','ember','ember')+' '+LEFT(@d,2)
SELECT @m/=min(n),@d/=min(n)
FROM
(
  SELECT number
  FROM spt_values
)x(n)
WHERE
  @m%n+@d%n=0
  and n>1
END

Hmm ... orada ilk iki çizgi ne yapıyor ???
Outgolfer Erik

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ ilk satırı bu betik için hangi veritabanının kullanılacağını söyler, ikinci satırı girdi değişkenini bildirir. Nerede komut dosyası yürütmek ve giriş değişkeninin ne olduğunu söylemek tanımlamak olarak onları dahil
etmedim

'12/2'İkinci satırda bir görüyorum , bana gerçeği söylediğinden emin misin?
Outgolfer Erik

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Korkarım Sorunuzu anlamıyorum
t-clausen.dk

Ben de, yanlış yazılmış gibi görünüyor ... STDIN SQL desteklenen ve varyantları ise emin değilim olsa da, kodlanmış tarihini kullanarak düşünüyorum Septemberile Septemper. 'temper','ober','ember','ember')+' '+LEFT(@d,2)
Outgolfer Erik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.