Print My Block Schedule

My high school, and many others implement a type of schedule called a Rotating Block Schedule. This is a way for people to have 8 classes, but on have 6 periods in a school day.

There are four days in a block schedule that repeat over and over, and have nothing to do with the actual days of the week. Each are assigned a number [1-4].

The way the schedule works is that you list all your morning classes, periods 1-4: [1, 2, 3, 4]. This is your schedule for the first day, or Day 1. The rest of the days just rotate the list: [2, 3, 4, 1] , [3, 4, 1, 2], [4, 1, 2, 3].

However, the last period in the morning is "dropped" and you don't see that teacher that day. Hence the days are: [1, 2, 3], [2, 3, 4], [3, 4, 1], [4, 1, 2].

The afternoon is the same, except that it uses periods 5-8 instead: [5, 6, 7], [6, 7, 8], [7, 8, 5], [8, 5, 6].

All this rotating is hard to keep track of, so you have to write a program to print out my schedule given what day it is as input. Your code has to place Homeroom and Lunch in the correct spots. Here is the exact output your code needs to have for inputs 1-4:

Homeroom    Homeroom    Homeroom    Homeroom
Period 1    Period 2    Period 3    Period 4
Period 2    Period 3    Period 4    Period 1
Period 3    Period 4    Period 1    Period 2
Lunch       Lunch       Lunch       Lunch
Period 5    Period 6    Period 7    Period 8
Period 6    Period 7    Period 8    Period 5
Period 7    Period 8    Period 5    Period 6


But Wait - One more thing!

Sometimes, on the first day of school, or on other special days, my school has a "Day 0". This just means that I will have all my classes that day along with homeroom and lunch. Your code will have to deal with Day 0's. Here is the output for a Day 0:

Homeroom
Period 1
Period 2
Period 3
Period 4
Lunch
Period 5
Period 6
Period 7
Period 8


This is so shortest code in bytes wins!

• Are there 4 days in the week? Or would the first Friday loop back to 1, 2, 3, 5, 6, 7? – Zach Gates Sep 15 '15 at 0:37
• @ZachGates only 4 days in the *week*. The block schedule would be out of sync with the actual school week. – Maltysen Sep 15 '15 at 0:39
• When are "Day 0"s used? How do we know which week we're picking from, and how many "Day 0"s have occurred so far? – Zach Gates Sep 15 '15 at 0:42
• @ZachGates Isn't that irrelevant? You just have to supply one output for one input. There are only 5 distinct outputs. – mınxomaτ Sep 15 '15 at 0:44
• @ZachGates There are 5 possible inputs. The 5 outputs that correspond to them are listed verbatim in the challenge. – Doorknob Sep 15 '15 at 0:46

Snowman 1.0.2, 190 bytes

}vg10sB*:#NdE*!1*"Homeroom
"sP0vn3nR:|%+#nA4NmO'"Period "sP'!#nAtSsP"
"sP|%;ae|"Lunch
"sP5*|ae;:"Homeroom
"sP0vn4nR*#:"Period "sPNiNtSsP"
"sP;aE"Lunch
"sP#:"Period "sP5nAtSsP"
"sP;aE;#bI


That leftmost column actually looks pretty nice, doesn't it?

...

... who am I kidding, I'd rather program in PHP than this.

}vg10sB*   // store day # in permavar
// big if statement coming up, depending on whether the input (n) is 0 or not

// THE FOLLOWING BLOCK IS FOR N != 0
:

#NdE*      // decrement number (because we like 0-based indeces) and re-store
!1*        // store the number 1 in permavar ! for later
"Homeroom
"sP        // print "Homeroom"
0vn3nR     // generate [0 1 2]
// for each element in this array...
:
|%            // shuffle around some variables so we have room
+#nA          // add day number (in permavar +)
4NmO          // modulo by 4
'"Period "sP  // print "Period "
'!#nAtSsP     // add whatever is in permavar ! and print
"
"sP               // print a newline
|%            // return variables to their original state
;ae
// this is a rare occasion in which we use "ae" instead of "aE"
// we use non-consume mode here because we need the block again
// since we've used a permavar ! to determine what to add to the period number,
//   we can set the permavar to 4 more than it used to be and run the same
//   exact block
|"Lunch
"sP        // print "Lunch"
5*         // store the number 5 in permavar !, as described above
|ae        // run the same block over the same array again

;

// THE FOLLOWING BLOCK IS FOR N == 0

:

// after much frustration, I have determined that the easiest way to go about
//   this is to simply code the "day 0" separately
// yes, snowman is *that* bad
"Homeroom
"sP           // you know the drill
// for each number in [0 1 2 3]
0vn4nR*#:
"Period "sP
NiNtSsP  // increment and print
"
"sP
;aE
"Lunch
"sP           // same stuff from here
// only interesting thing is we saved the range from before with *#, so we can
//   get it back easily
#:"Period "sP5nAtSsP"
"sP;aE

;

#bI


Thoughts and musings:

• Firstly, I definitely need to implement a prettier way of printing newlines. Because strings with newlines in an indented block are super ugly.

• I like my trick with ae—you rarely see the ae operator without the E capitalized in real Snowman code. (You also rarely see Snowman code that's not written by me, but that's besides the point.)

For the uninitiated, Snowman has two ways to call operators. "Consume" mode, and "non-consume" mode. "Consume" mode will call the operator with the variables requested and then discard the variables. Non-consume mode will call the operator and still leave the variables intact.

Which is usually not what you want with ae (array-each), because the block you're calling on each element will stay there and get in your way, using up a precious one of the eight variables.

However, this is a rare situation in which ae is actually what we want (see the comments in the code for further explanation).

• I'm really, really starting to think that Snowman needs more than two modes, other than just "consume" and "do-not-consume." For example, with aa (basically array indexing), you only get two ways to call it:

["foo" 0] -> ["f"]
["foo" 0] -> ["foo" 0 "f"]


(Snowman doesn't use a stack/array structure, but that's simply being used for clarity here.)

It's pretty common that you want ["foo" "f"] (i.e. consume the index variable, but not the original one). It's a super convoluted process to get rid of that annoying 0 if you use "do-not-consume" mode.

A similar thing happens when you call "array-each" in "do-not-consume" mode, as is done here. The array and the block stick around, even during the execution of said block. Which is... really, really weird.

Then again, the design goal of Snowman is to be as confusing as possible, so I'm not sure whether this is a problem at all.

CJam, 65 55 bytes

ri_5,m<0-_W<\?_4f+]"HomeroomLunch"8/.{N@{"Period "\N}%}


Try it online in the CJam interpreter.

Python 3, 193192182168 165 bytes

u=int(input())
print('Homeroom')
r=['Period '+i for i in("123567234678341785412856"[(u-1)*6:u*6]if u else"12345678")]
r.insert(len(r)//2,'Lunch')
for i in r:print(i)


Just a quick solution.

Python 2, 161 bytes

u=int(input())
print'Homeroom'
r=['Period '+i for i in("123567234678341785412856"[(u-1)*6:6*u]if u else"12345678")]
r.insert(len(r)//2,'Lunch')
print'\n'.join(r)

• You can save by replacing the for loop with a "\n".join – Maltysen Sep 15 '15 at 2:34
• It's the same amount of bytes in Python 3, but it would help in Python 2. @Maltysen I'll add it though. :P – Zach Gates Sep 15 '15 at 2:37

Pyth, 51 bytes

"Homeroom"j"Lunch
"c2jb+L"Period "+J?QP.<S4tQS4+L4J