20
\$\begingroup\$

Challenge

Given the phase of the moon, draw it using ASCII art.

Your program must handle new moon, waxing crescent, first quarter, waxing gibbous, full moon, waning gibbous, last quarter, and waning crescent. Your input will be an integer.

0 -> new moon
1 -> waxing crescent
2 -> first quarter
3 -> waxing gibbous
4 -> full moon
5 -> waning gibbous
6 -> last quarter
7 -> waning crescent

The ASCII art is all placed on a 16x8 grid (because character dimension ratios). You can replace . with any character and # with any other non-whitespace character.

The output for new moon should be:

................
................
................
................
................
................
................
................

For waxing crescent:

..........######
............####
.............###
.............###
.............###
.............###
............####
..........######

For first quarter:

........########
........########
........########
........########
........########
........########
........########
........########

For waxing gibbous:

......##########
....############
...#############
...#############
...#############
...#############
....############
......##########

And for full moon:

################
################
################
################
################
################
################
################

The waning crescent is just the waxing crescent with each line reversed, as with the waning gibbous and the waxing gibbous, and the first and last quarter.

Rules

  • Standard Loopholes Apply
  • You may choose to output waxing/waning in the opposite direction if you want, though it should make no difference (the graphics shown in this question are for the northern hemisphere)
  • Your output must be exactly as specified. Your newlines can be any reasonable line separator, and you may have a trailing newline if you would like.
\$\endgroup\$
  • 5
    \$\begingroup\$ Relevant xkcd. \$\endgroup\$ – Martin Ender May 17 '17 at 5:55
  • \$\begingroup\$ "though it should make no difference" - saved me a byte (I hope I got it right) :) \$\endgroup\$ – Jonathan Allan May 17 '17 at 9:19
  • 1
    \$\begingroup\$ Does it have to be ASCII art? MoonPhase["Icon"] is 17 bytes in Mathematica… \$\endgroup\$ – Not a tree May 17 '17 at 10:27
  • \$\begingroup\$ @JonathanAllan Oh nice. Well then it might make a difference :P \$\endgroup\$ – HyperNeutrino May 17 '17 at 11:33
  • \$\begingroup\$ @lanlock4 You stated one of the reasons why I made it ASCII art. Also yes it does have to be ASCII art. \$\endgroup\$ – HyperNeutrino May 17 '17 at 11:34
7
\$\begingroup\$

Jelly,  43 32 bytes

-7 bytes moving from bit-mask to comparison-mask
-2 bytes with some tacit programming improvements
-1 byte moving to the southern hemisphere
-1 byte - use the all-new ɓ chain separator ...its first ever use!

“>,##‘m0Dm€0ż@€4Ḷ¤Œṙɓ%4>C¹⁸:4¤?Y

Uses the characters 0 for . and 1 for #.

All cases in a test suite at Try it online!

How?

Builds a mask capturing the first four phases, and rather than reversing the lines complements the resulting values of the modulo-4 phase result when the phase div-4 is non-zero.

I originally built a bit mask, but the mask values were 0,8,12, and 14 - 0000, 1000, 1100, and 1110 - these have phase leading ones - so a comparison-mask could be used instead.

“>,##‘m0Dm€0ż@€4Ḷ¤Œṙɓ%4>C¹⁸:4¤?Y - Main link 1: number phase
“>,##‘                           - code-page index literal [62,44,35,35]
      m0                         - reflect -> [62,44,35,35,35,35,44,62]
        D                        - decimalise -> [[6,2],[4,4],[3,5],[3,5],[3,5],[3,5],[4,4],[6,2]]
         m€0                     - reflect €ach -> [[6,2,2,6],[4,4,4,4],[3,5,5,3],[3,5,5,3],[3,5,5,3],[3,5,5,3],[4,4,4,4],[6,2,2,6]]
                 ¤               - nilad and link(s) as a nilad:
               4                 -   literal 4
                Ḷ                -   lowered range -> [0,1,2,3]
            ż@€                  - zip (reverse @rguments) for €ach -> [[[0,6],[1,2],[2,2],[3,6]],[[0,4],[1,4],[2,4],[3,4]],[[0,3],[1,5],[2,5],[3,3]],[[0,3],[1,5],[2,5],[3,3]],[[0,3],[1,5],[2,5],[3,3]],[[0,3],[1,5],[2,5],[3,3]],[[0,4],[1,4],[2,4],[3,4]],[[0,6],[1,2],[2,2],[3,6]]]
                  Œṙ             - run-length decode -> [[0,0,0,0,0,0,1,1,2,2,3,3,3,3,3,3],[0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3],[0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3],[0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3],[0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3],[0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3],[0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3],[0,0,0,0,0,0,1,1,2,2,3,3,3,3,3,3]]
                                    -   i.e.: 0000001122333333  -
                                              0000111122223333  - Marking out the separate
                                              0001111122222333  - regions as filled up by
                                              0001111122222333  - the phases of the moon in
                                              0001111122222333  - the southern hemisphere.
                                              0001111122222333  -
                                              0000111122223333  -
                                              0000001122333333  -
                    ɓ            - dyadic chain separation & swap arguments, call that m
                     %4          - phase mod 4
                       >         - greater than? (vectorises across m) 1 if so 0 if not
                              ?  - if:
                             ¤   -   nilad followed by link(s) as a nilad:
                          ⁸      -     link's left argument, phase
                           :4    -     integer divide by 4
                        C        - then: complement
                         ¹       - else: identity (do nothing)
                               Y - join with newlines
                                 - implicit print
\$\endgroup\$
  • 3
    \$\begingroup\$ that's not a language, it's modem noise... \$\endgroup\$ – Alnitak May 17 '17 at 16:27
  • \$\begingroup\$ @Alnitak Welcome to PPCG! Did you join this PPCG.SE just so you could make that comment? ;) \$\endgroup\$ – HyperNeutrino May 18 '17 at 1:47
8
\$\begingroup\$

JavaScript (ES6), 121 ... 103 92 bytes

f=(n,i=128)=>i--?f(n,i)+(i%16?'':`
`)+'.#.'[i%16+4*n-~-'31000013'[n&1?i>>4:1]*~-(n&2)>>4]:''

Demo

f=(n,i=128)=>i--?f(n,i)+(i%16?'':`
`)+'.#.'[i%16+4*n-~-'31000013'[n&1?i>>4:1]*~-(n&2)>>4]:''

o.innerHTML=f(0)
<input type="range" oninput="o.innerHTML=f(this.value)" value=0 min=0 max=7><pre id=o>

\$\endgroup\$
  • \$\begingroup\$ Aw, I wanted to give this a stab at lunchtime. Doubt I would have beaten you, though. \$\endgroup\$ – Shaggy May 17 '17 at 9:46
4
\$\begingroup\$

Haskell, 98 90 bytes

f i=do{a<-[3,1,0,0,0,0,1,3];[".#."!!div(i*4+x+[0,a-1,0,1-a]!!mod i 4)16|x<-[0..15]]++"\n"}

It loops through the rows and columns using the list monad (a do block for rows and a list comprehension for columns) and determines which character for each cell using a expression of the input (i), offset value for the row (a), and column index (x).

Saved 8 bytes by simplifying the subexpression for the true offset.

\$\endgroup\$
3
\$\begingroup\$

Python 2, 144 142 127 bytes

i=input()
a,b='#.'[::i/4*2-1]
i%=4
for x in range(8):y=(int(abs(x-3.5))or 1)+2;y=[y,16-y][i>2];y=[i*4,y][i%2];print(16-y)*a+b*y

Try it online!

Can definitely be golfed further, tips are appreciated :)

Golfed off 1 byte thanks to undergroundmonorail!

Golfed off many bytes thanks to ovi and Mego because I'm a fool who forgets to not use 4 spaces for codegolf :)

\$\endgroup\$
  • \$\begingroup\$ if i>2:y=16-y could be changed to y=[16-y,y][i>2], which is longer, but with liberal use of semicolons would allow your loop to be a one-liner to save several bytes. \$\endgroup\$ – Mego May 17 '17 at 21:12
2
\$\begingroup\$

PHP, 105 Bytes

for(;$i++<8;)echo($p=str_pad)($p("",[16,16-$b=_64333346[$i],8,$b][3&$a=$argn],_M[$a/4]),16,M_[$a/4])."
";

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ why not $a/4? The indexing will do the cutting. :) \$\endgroup\$ – Titus May 18 '17 at 2:30
  • \$\begingroup\$ @Titus i have not know it. Thank You \$\endgroup\$ – Jörg Hülsermann May 18 '17 at 9:53
1
\$\begingroup\$

Mathematica, 125 bytes

s=Switch;Grid@If[1<#<6,#&,1-#&][s[m=#~Mod~4,0,0,2,1,_,1-{3.4,5}~DiskMatrix~{8,16}]s[m,1,h=Table[Boole[i>8],8,{i,16}],_,1-h]]&

Returns a grid using 1 and 0 instead of . and # respectively.

It works using two masks, one circular one and one half-shaded one, and logically combining them to get the appropriate shapes.

The two masks are made with 1-{3.4,5}~DiskMatrix~{8,16} for the circular one, and Table[Boole[i>8],8,{i,16}] for the half one. The logic is as follows:

output = f(a AND b)

where f, a and b are:

n | f    a  b
--+-----------
0 | NOT  F  ◨ 
1 | NOT  ○  ◧ 
2 | 1    T  ◨
3 | 1    ○  ◨
4 | 1    F  ◨ 
5 | 1    ○  ◧ 
6 | NOT  T  ◨ 
7 | NOT  ○  ◨

The logic is simulated with 1s and 0s by using multiplication for AND and x -> 1-x for NOT.

A bonus (non-ASCII) solution, for 28 bytes: IconData["MoonPhase",#/4-1]&

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.