Loves me, loves me not

45

4

Loves me, Loves me not

This simple kids' game is old, but still popular. Since we are living in 21st century now, let's digitize it!

Specification

Program must take no input, unless you are using a language that can't generate random seed - in that case you are allowed to take the seed as an input. Your task is to write a program that will output randomly a total of 3 to 20 lines inclusive: "Loves me..." and "Loves me not..." in turns, as in the game (and one additional line; keep reading).

However, there are some restrictions. Each line should be followed by newline. The first line must be "Loves me...". The last line (either "Loves me" or "Loves me not") should end with exclamation mark or a single dot, respectively. After the last line, you need to output either a heart( <3 ) or a broken heart ( </3 ) in the new line, depending whether "Loves me!" or "Loves me not." was the last sentence.

Trailing whitespace are allowed.

Example Output

Output:

Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me!
<3

Another output:

Loves me...
Loves me not...
Loves me...
Loves me not.
</3

This is the , so the shortest entry wins!

Also, my first challenge :) Good luck!

MatthewRock

Posted 2015-09-15T15:10:44.523

Reputation: 913

Are there any restrictions on the distribution of the number of lines, i.e., should it be uniformly random, or is it enough that all lengths between 3 and 20 have a positive probability? – Zgarb – 2015-09-15T15:13:15.853

I didn't think about this, but I'd say that any distribution is fine - so they don't have to be uniformly random. – MatthewRock – 2015-09-15T15:14:26.947

Is it 3 to 20 ([3, 20)) or 3 up to including 20 ([3, 20])? – orlp – 2015-09-15T15:15:17.790

@orlp Edited to adress that concern. 3 is minimum, 20 is maximum. So 20 lines is ok, but no 21. – MatthewRock – 2015-09-15T15:17:14.800

1@MatthewRock What if the language we want to use can't seed a random number on their own? Can the user supply a random seed? – mınxomaτ – 2015-09-15T15:35:55.933

@minxomat I'd prefer it to be random-random, so no user should generate randomness. Couldn't you get time or anything similar? – MatthewRock – 2015-09-15T17:31:42.547

@minxomat Are you trying to do this in Brainf*** or what? – mbomb007 – 2015-09-15T17:33:31.173

@MatthewRock No. There are a few languages that do not have support for timers. I'd like to require a seed from the user. I still have to implement a proper PRNG, so the challenge isn't easier for me. – mınxomaτ – 2015-09-15T17:43:20.600

@minxomat what language is it? – MatthewRock – 2015-09-15T17:50:36.123

@MatthewRock Brainfuck. – mınxomaτ – 2015-09-15T17:50:54.697

@MatthewRock let him take the seed as a input. – Mindwin – 2015-09-15T18:06:38.653

3@minxomat Whatever, it's just a game. Go on, changed the rules. – MatthewRock – 2015-09-15T18:25:39.543

Answers

23

Pyth, 54 53 51 50 48 bytes

pj+*3\.bm+W~!Z"Loves me"" not"+3O18@".!"Z%hZ"</3

orlp

Posted 2015-09-15T15:10:44.523

Reputation: 37 067

%2tWZ"<</33 for the heart printing saves 1. Not convinced this is the best way though. – FryAmTheEggman – 2015-09-15T15:32:33.613

@FryAmTheEggman Made it save two. – orlp – 2015-09-15T15:36:05.910

Merging the last two strings together saves another one, but I had to switch back to my %. – FryAmTheEggman – 2015-09-15T15:43:57.633

@".!"Z%hZ"</3 saves two bytes – Jakube – 2015-09-15T20:00:29.290

Since there has been no entry for few days, I'm accepting this answer. Congratulations! – MatthewRock – 2015-09-24T15:02:28.020

23

CJam, 53 50 49 bytes

Thanks to Dennis for saving 1 byte.

Imr3+{"Loves me"X!:X" not"*'.3*N}*&"!."X=N'<'/X*3

Test it here.

Explanation

The code just dumps the string in bits and pieces onto the stack, which is printed automatically at the end of the program:

Imr3+         e# Generate a random number in [3,20]
{             e# Execute this block that many times.
  "Loves me"  e#   Push "Loves me", we always need that.
  X!:X        e#   Toggle X (initially 1) between 0 and 1 and leave it on the stack.
  " not"*     e#   Repeat " not" that many times, removing it on every other line.
  '.3*N       e#   Push "..." and a newline.
}*
&             e# Set intersection of "..." and newline, turning them into an empty array.
"!."X=        e# Select "!" or "." based on the last value of X.
N'<           e# Push a newline and "<".
'/X*          e# Include "/" or not depending on the last value of X.
3             e# Push a 3.

Martin Ender

Posted 2015-09-15T15:10:44.523

Reputation: 184 808

one could imagine CJam would've been developed exclusively for code-golf ^^ – larkey – 2015-09-15T19:55:58.783

11@larkey but it is... – MatthewRock – 2015-09-15T21:14:29.113

@larkey CJam is derived from GolfScript, and GolfScript (as its name implies) is designed for golfing. – Chris Jester-Young – 2015-09-16T19:16:54.837

@ChrisJester-Young it was ment a bit tongue-in-cheek ;-) – larkey – 2015-09-16T21:49:13.510

17

Brainfuck, 2766 bytes (currently invalid)

Just because. I'll add an ungolfed version later.

Code

>+<+[>[>[-]+<-]>[<+>>+[->,----------[<+>[>>>>>>>>>+<<<<<<<<<-]>>>>>>>>>[>+<<<<<<<<<<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]]<]<-]>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>>>>>>>>>>>[<<<<<<<<<<+>>>>>>>>>>-]>[<<<<<<<<<<+>>>>>>>>>>-]<<<<<<<<+++++++[<+++++++++++>-]<[<<[>>>>>>>>>>+<<<<<<<+<<<-]>>>[<<<+>>>-]<<[>>>>>>>>>+<<<<<<<+>+<<<-]>>>[<<<+>>>-]<[>>>>>>>>+[<<<<<<<+>+>>>>>>-]<<<<<<[>>>>>>+<<<<<<-]+<[>-<[-]]>[>>>>>+<<<<<-]<<-]<-]++++++[>++++++++<-]>-[<<[>>>>>>>>>+<<<<<<<<+<-]>[<+>-]>-]<<<[-]>[-]+++++[<+++++>-]<[>>>>>>>>>>>+[<<<<<<<<<<+>+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]+<[>-<[-]]>[>>>>>>>>+<<<<<<<<-]<<-]++++++[>>>>>>>>>>+++++++++<<<<<<<<<<-]>>>>>>>>>>[<<+<<<<<<<<+>>>>>>>>>>-]<<<<<<<<<<[>>>>>>>>>>+<<<<<<<<<<-]>>>>>>>[-]>[<+<<<<<<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[-]++++++++++++++++++++<<[<<<+>>>-]>>[<<<<<<<<+>+<<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>>[>>[<+<<<+>>>>-]<<<<[>>>>+<<<<-]+>>>[<<->>>-<<<<->>>[-]]<<<[>>[-]+<<-]>>-]>>[>>>-<<<[-]]<<<[-]>>>>>>>>[-]<[>+<<<<<<<<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>>>>[-]+++<<<[<<<<<+>>>>>-]>>>[<<<<<<<<<<<+>+<<+>>>>>>>>>>>>-]<<<<<<<<<<<<[>>>>>>>>>>>>+<<<<<<<<<<<<-]>>[>>[<+<<<+>>>>-]<<<<[>>>>+<<<<-]+>>>[<<->>>-<<<<->>>[-]]<<<[>>[-]+<<-]>>-]<[>>>>>>>>-<<<<<<<<[-]]>>>[-]>>>[<<<<<<<+>>>>>>>-]<<<<<<<[>>>>>>>-<<<<<<<[-]]>>>>>>>>>[<<<<<<<<<+>+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]<[>>>>>>>[-]-<<<<<<<[-]]>>>>>>>[>>>>>>+<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>+++++++++++[>+++++++>++++++++++>+++++++++>+++>++++<<<<<-]>-.>+.+++++++.>++.<---.>>-.<<------.>.>>++...[-]<[-]<[-]<[-]<[-]<++++++++++.[-]>>>>>>>[-]>[<+<<<<<<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>>>>>>->[-]<[>+<-][-]>[<+<<<<<<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[-]<<[<<<<<<+>>>>>>-]->>[<<<<<<<<-<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>[>>>>>>+<<<<<<[-]]<->>>>>>>[<<<<<<<->>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[>>>>>>>>+<<<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]<[>[-]+<-]>[<+>>++++++[>++++++++++<-]>.---------.[-]<<<-<->>-]>>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>+++++++++++[>+++++++>++++++++++>+++++++++>+++>++++<<<<<-]>-.>+.+++++++.>++.<---.>>-.<<------.>.>.<<+.+.+++++.>>>++...[-]<[-]<[-]<[-]<[-]<++++++++++.[-]>>>>>>>[-]>[<+<<<<<<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>>>>>>->[-]<[>+<-][-]>[<+<<<<<<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[-]<<[<<<<<<+>>>>>>-]->>[<<<<<<<<-<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>[>>>>>>+<<<<<<[-]]<->>>>>>>[<<<<<<<->>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[>>>>>>>+<<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]<[>[-]+<-]>[<+>>++++++[>++++++++++<-]>.-------------.++++.<<<<->>-]<<]

Pseudocode

loop
    get a random byte
until random byte is >2 and <21

point to byte
[
    output "Loves me..."
    decrease byte by 1
    if byte is 0
        output "<3"
        exit
    eif
    output "Loves me not..."
    decrease byte by 1
]
output "</3"

Sample

When run, the program enters an interactive session waiting for input. Input should be a number. This number is used as a seed.

Seed: 1 (random number is 5, takes 218,168,042 operations)

1              
Loves me...    
Loves me not...
Loves me...    
Loves me not...
Loves me...    
<3             

Seed: 3 (random number is 20, takes 463,253,048 operations)

3
Loves me...
Loves me not...
(...)
Loves me...
Loves me not...
</3

I'd suggest that you do not seed with 6, as it takes 2,105,900,375 iterations to compute the result :).

Compiling / Running

You need a fast interpreter for this. No online interpreter I've tested could handle the execution speed. The ips (iterations per second) should be more than 100,000,000. So I came up with another solution.

This is a Brainfuck to C compiler written in Brainfuck. You can use any online interpreter to transpile my code to pure C. I suggest using brainfuck.tk. Paste my code in the stdin input, past this code in the code input:

+++[>+++++<-]>>+<[>>++++>++>+++++>+++++>+>>+<++[++<]>---]>++++.>>>.+++++.>------.<--.+++++++++.>+.+.<<<<---.[>]<<.<<<.-------.>++++.<+++++.+.>-----.>+.<++++.>>++.>-----.<<<-----.+++++.-------.<--.<<<.>>>.<<+.>------.-..--.+++.-----<++.<--[>+<-]>>>>>--.--.<++++.>>-.<<<.>>>--.>.<<<<-----.>----.++++++++.----<+.+++++++++>>--.+.++<<<<.[>]<.>>,[>>+++[<+++++++>-]<[<[-[-<]]>>[>]<-]<[<+++++>-[<+++>-[<-->-[<+++>-[<++++[>[->>]<[>>]<<-]>[<+++>-[<--->-[<++++>-[<+++[>[-[-[-[->>]]]]<[>>]<<-]>[<+>-[<->-[<++>-[<[-]>-]]]]]]]]]]]]]<[-[-[>+<-]>]<[<<<<.>+++.+.+++.-------.>---.++.<.>-.++<<<<.[>]>>>>>>>>>]<[[<]>++.--[>]>>>>>>>>]<[<<++..-->>>>>>]<[<<..>>>>>]<[<<..-.+>>>>]<[<<++..---.+>>>]<[<<<.>>.>>>>>]<[<<<<-----.+++++>.----.+++.+>---.<<<-.[>]>]<[<<<<.-----.>++++.<++.+++>----.>---.<<<.-[>]]<[<<<<<----.>>.<<.+++++.>>>+.++>.>>]<.>]>,]<<<<<.<+.>++++.<----.>>---.<<<-.>>>+.>.>.[<]>++.[>]<.>[.---->.---,....]

Download the source and compile it:

gcc.exe -c main.c -o main.o
gcc.exe main.o -o loveme.exe

You can also run a copy of the C code online here: via. CodingGround.

Optimizations

There is still some work to do, but the cell re-use is almost optimal.

Remarks

You can use words or phrases as a seed:

Programming Puzzles & Code Golf
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
Loves me not...
Loves me...
<3

mınxomaτ

Posted 2015-09-15T15:10:44.523

Reputation: 7 398

3+1 for having the audacity to write a PRNG in Brainfuck ... – AdmBorkBork – 2015-09-15T19:36:53.207

@TimmyD There are better ways to write PRNGs in BF, but most of them are time based (run the program, and stop execution at some point, then read memory), but that would require user interaction and two separate programs, which is against the rules. – mınxomaτ – 2015-09-15T19:43:49.423

3Nice pseudocode. More people should do that, especially since half the golfing languages are basically unreadable if you don't know them. – The_Basset_Hound – 2015-09-16T01:54:22.787

3Unfortunately your output is wrong. Last "Loves me" should end with an exclamation point(so, "Loves me!"), and "Loves me not" should end with single dot("Loves me not."). – MatthewRock – 2015-09-16T14:06:18.390

@MatthewRock Will fix. – mınxomaτ – 2015-09-16T14:20:52.137

1Can we have some pseudocode of the RNG? – Beta Decay – 2015-09-19T21:27:40.453

Link is borked. – Loovjo – 2016-07-13T20:45:13.073

7

Javascript (ES6), 119 104 99 98 bytes

for(i=new Date%18+3,s=i&1?`!
<3`:`.
</3`;i--;)s=`...
Loves me`+(i&1?' not':'')+s
alert(s.slice(4))

Mwr247

Posted 2015-09-15T15:10:44.523

Reputation: 3 494

Good one! It may be shorter to use string concatenation for creating the heart, and possibly in the creation of each line. Mind if I use the new Date trick in my answer? – ETHproductions – 2015-09-15T18:42:35.220

@ETHproductions Go for it, so long as you're fine with me using those hearts haha (and why didn't I use alert... for some reason I convinced myself arrow functions would be shorter, but needing return negates that...). I actually just got it down to 104 now with some other tricks as well =) – Mwr247 – 2015-09-15T18:46:51.817

Dang... nice job :) I keep rearranging mine, but always end up at 104. – ETHproductions – 2015-09-15T18:58:13.007

The breakthrough for me was combining the length/iteration variable by concatenating backwards, and defining the hearts in the initialization. I tried it a while back with little savings, but your heart simplification made it much more efficient. – Mwr247 – 2015-09-15T19:03:36.730

Wait a minute... Trying this, I get Loves me not... Loves me... Loves me not! <3 and Loves me not... Loves me... Loves me not... Loves me. </3. I think you'll have to change one of the conditionals to fix this. EDIT: Oh, just switch the '' and ' not' in the fourth line. – ETHproductions – 2015-09-15T19:07:57.070

@ETHproductions Seems to reverse on me every time I touch anything to do with that iterator haha. Thanks! – Mwr247 – 2015-09-15T19:12:23.937

6

Python, 147

from random import*;t=randint(3,20)
print"\n".join("LLoovveess  mmee  n o t"[i%2::2].strip()+"..."*(i<t-1)for i in range(t))+"!.\n\n<<3/ 3"[t%2::2]

Uses the from random import* instead of import random and randint instead of randrange to save a few bytes. There's probably some bytes left to golf out.

Loovjo

Posted 2015-09-15T15:10:44.523

Reputation: 7 357

3The alternation "LLoovveess mmee n o t"[i%2::2].strip() seems needlessly complicated. Can't you just do "Loves me"+~i%2*" not"? – xnor – 2015-09-16T04:17:01.633

Even ["Loves me","Loves me not"][i%2] is more optimal, since you're now wasting chars on .strip() and a couple of spaces. But yes, use xnor's code – nitro2k01 – 2015-09-18T08:36:01.687

6

Javascript (ES6), 110 102 bytes

a='';for(i=j=new Date%18+3;i--;)a+='Loves me'+(j-i&1?'':' not')+(i?`...
`:j&1?`!
<3`:`.
</3`);alert(a)

This was a short but fun little challenge. It may be possible to shorten more. Thanks to Mwr247 for some byte-saving tricks!

Alternate version using repeat(), 105 bytes:

a='';for(i=j=new Date%18+3;i;)a+='Loves me'+' not'.repeat(j-i--&1)+(i?`...
`:j&1?`!
<3`:`.
</3`);alert(a)

Darn JS 5+-char built-in names. Oh well. Suggestions welcome!

ETHproductions

Posted 2015-09-15T15:10:44.523

Reputation: 47 880

Impressive condensing. I'm curious though, why the 18+3|0? – Mwr247 – 2015-09-15T18:58:43.500

@Mwr247 Oh, duh, that was from when I used Math.random(). Guess it's not necessary now. – ETHproductions – 2015-09-15T18:59:37.253

5

Perl, 85

print$_?'...
':'','Loves me',$c=$_%2?' not':''for 0..3+rand 18;print$c?'.
</3':'!
<3'

Dom Hastings

Posted 2015-09-15T15:10:44.523

Reputation: 16 415

5

Ruby, 91 bytes

(n=3+rand(18)).times{|i|puts"Loves me"+[""," not"][i%2]+(i<n-1?"...":i%2>0?".
</3":"!
<3")}

daniero

Posted 2015-09-15T15:10:44.523

Reputation: 17 193

5

Common Lisp 106 104 bytes

(format t"~{Loves me~[ not~]~#[~:*~[.~%</~;!~%<~]3~:;...~]~%~}"(subseq'#1=(1 0 . #1#)0(+ 3(random 18))))

This only works on lisps that don't check for a proper sequence (e.g. cmucl, sbcl, clisp) ccl will check for circularity and error out on default safety level. ecl will loop forever.

Explanation:

#1=(1 0 . #1#) generates a circular list containing 1 and 0 and subseq is used to make a list of length [3,20] (this is the only non-portable part, as subseq is only required by the standard to work on proper (i.e. non-circular) lists).

Our format is now operating on a list of 1 0 1 0... of length [3,20]

Explanation of format directives:

~{ iterates over this list

~[ followed by any number of ~; and terminated with ~] will select the Nth item, based on the value of the format argument. This is used here so that the first item in a ~[ will be the "loves me not" case and the second one the "loves me" case. Note that with ~[ a separator of ~:; selects a default case.

~#[ works like ~[ except the argument is the number of remaining arguments. 0 remaining arguments means we are at the end, the default case is to print ...

~:* backs up the argument list one position, which allows us to print the correct trailer.

Jason

Posted 2015-09-15T15:10:44.523

Reputation: 201

1This was a group effort by the #lisp IRC channel. Many thanks to phf for the clever iterative format-string and the subseq hack. – Jason – 2015-09-16T17:28:04.567

4

Python 2, 161 159 156 144 bytes

from random import*;a=randrange(3,21)
for i in range(a):print'Loves me'+i%2*' not'+('...'if i!=a-1 else'.'if i%2 else'!')
print['<3','</3'][i%2]

It's 39 bytes just to get the random number.

A big thank you to muddyfish, fryamtheeggman, and orlp for their help.

PYG, 109 bytes

a=RR(3,21)
for i in R(a):P('Loves me'+i%2*' not'+('...'if i!=a-1 else'.'if i%2 else'!'))
P(['<3','</3'][i%2])

Celeo

Posted 2015-09-15T15:10:44.523

Reputation: 520

You can do the range statement in a single line. you can also do import random as r – Blue – 2015-09-15T16:07:06.680

you can also put the contents of the last print statement onto the line above. – Blue – 2015-09-15T16:10:51.300

I think you can change print'</3'if i%2 else'<3' to print['<3','</3'][i%2] to save 3 bytes. – Kade – 2015-09-15T16:20:18.787

Yes indeed I can; thanks! – Celeo – 2015-09-15T16:22:21.727

Thanks! Interestingly, import random as r;a=r.randrange(3,21) and import random;a=random.randrange(3,21) are the same length. – Celeo – 2015-09-15T16:24:58.710

Many standard golfs – FryAmTheEggman – 2015-09-15T16:29:10.453

['...','!','.'][(i==a-1)*(1+i%2)] and ' not'*(i%2). – orlp – 2015-09-15T16:29:31.627

Thanks FryAmTheEggman and orlp. I added parts of what you two suggested but would feel guilty taking all of FryAmTheEggman's comment. – Celeo – 2015-09-15T17:31:05.597

4

Julia, 98 bytes

r=rand(3:20)
for i=1:r println("Loves me"*(i%2>0?" not":"")*(i<r?"...":i%2>0?".\n</3":"!\n<3"))end

Ungolfed:

# Define a random number 3 ≤ r ≤ 20
r = rand(3:20)

for i = 1:r
    # The loveless lines occur when i is even
    println("Loves me" *
            (i % 2 > 0 ? " not" : "") *
            (i < r ? "..." : i % 2 > 0 ? ".\n</3" : "!\n<3"))
end

Alex A.

Posted 2015-09-15T15:10:44.523

Reputation: 23 761

4

UNIX shell, 193 bytes

t=$(seq 2 19|shuf|head -1)
l=t
p=...
while [ $t -ge 0 ];do
case $l:$t in t:0)p=!;h=\<3;;f:0)p=.;h=\</3;;esac
case $l in t)l=f;n=;; f)l=t;n=\ not;;esac
t=$((t-1))
echo Loves me$n$p
done
echo $h

Alois Mahdal

Posted 2015-09-15T15:10:44.523

Reputation: 151

4

Java, 210 209 203 200 177 bytes

  • flipped i%2==0 to i%2<1
  • trimmed { ... } braces for for-loop, moved e declaration to loop
  • re-ordered conditionals
  • removed modifiers and unnecessary parentheses, reworked Random usage and increment for i

Note: newline is added below for formatting on this site, the count above is for a single line.

class F{public static void main(String[]a){for(int e=3+(int)(Math.random()*18),i=0;++i<=e;)
System.out.println("Loves me"+(i%2>0?i<e?"...":"!\n<3":" not."+(i<e?"..":"\n</3")));}}

Ungolfed:

class F {
    public static void main(String[] a) {
        for (int e = 3 + (int) (Math.random() * 18), i = 0; ++i <= e; )
            System.out.println("Loves me" + (i % 2 > 0 ? i < e ? "..." : "!\n<3"
                    : " not." + (i < e ? ".." : "\n</3")));
    }
}

h.j.k.

Posted 2015-09-15T15:10:44.523

Reputation: 589

1You can save 13 bytes by removing public. – Luminous – 2015-09-16T14:12:45.580

@Luminous I'll still need to keep the one for main() though... – h.j.k. – 2015-09-16T14:55:17.513

@TimmyD I second that. – RK. – 2015-09-16T22:39:04.843

4

C, 123, 121, 109 106 characters (108 bytes)

(with a little ♥♥♥cheating♥♥♥)

O;main(o){for(o=time(O)%18+3;o-O++;printf("Loves me%s%s\n",O&1?"":" not",o-O?"...":O%2?"!\n♥":".\n</3"));}

There's also a broken heart Unicode point at 1f494, but I had difficulties finding a font which implements it.

Jens

Posted 2015-09-15T15:10:44.523

Reputation: 291

This shows 120 characters and 122 bytes... – AdmBorkBork – 2015-09-16T18:14:10.287

1I don't think you need O=0, because C auto-initialize ints to 0? – FryAmTheEggman – 2015-09-16T18:14:26.493

@FryAmTheEggman Good find! In a previous version I had O in main(o,O) where it had to be initialized. – Jens – 2015-09-16T18:18:54.623

Nice, I like it! I didn't think of using time as a random number... Clever! – MatthewRock – 2015-09-16T18:21:09.290

@MatthewRock If you think about it, all the other program using srand(time(0)) will change their answer with the same frequency. The srand is completely useless :-) – Jens – 2015-09-16T18:22:35.773

@TimmyD I believe it's the way the unicode character is counted. In vim, it was 123 bytes including the final newline. – Jens – 2015-09-16T18:24:51.667

Even though you "need" a trailing newline according to C documentation, most compilers actually don't care, and as long as one referenceable implementation works that way all the time, it's valid here :P

– FryAmTheEggman – 2015-09-16T18:31:32.867

Why don't you change ♥♥♥ for <3? It's actually 1 byte less. Plus, your answer - as for now - doesn't meet the requirements. – MatthewRock – 2015-09-16T19:12:06.223

@MatthewRock Guess I'm a bit anarchic and like to break^Wcreatively twist the rules. If the winner is the shortest program, C has no chance anyway, with CJam around. – Jens – 2015-09-16T19:28:35.140

@Jens Creatively twisting the rules is for [tag:popularity-contest]s, which this is not :P – Beta Decay – 2015-09-17T17:21:57.230

3

PowerShell, 121 119 111 Bytes

$i=2..19|Random;1..$i|%{"Loves me$(if(!($_%2)){" not"})..."};"Loves me$(if(!($i%2)){"!`n<"}else{" not.`n</"})3"

Edit--actually shorter to explicitly include "Loves me" rather than declaring $l

Edit2--forgot that I can golf for() loops by pipelining...durr...

Not too shabby. Uses inline code execution blocks $(...) to dynamically adjust the printed string as we're for()-looping. Note that because this uses an implicit Get- in front of Random to save a couple bytes, this may operate extremely slowly on certain PowerShell versions. Reference

Expanded below for clarification:

# Create a collection of (2,3,4,...18,19) and pipe it as input to Get-Random
$i = 2..19 | Get-Random

# Create a collection of (1,2,...$i-1,$i) and pipe it to seed a ForEach-Object loop
1..$i | ForEach-Object {
  if(!($_%2)) {
    # If the input number is even, we're on an even line
    Write-Output "Loves me not..."
  }
  Else {
    # The input number is odd
    Write-Output "Loves me..."
  }
}
If(!($i%2)) {
  # Our random number is odd
  Write-Output "Loves me!"
  Write-Output "<3"
}
Else {
  # Our random number is even
  Write-Output "Loves me not."
  Write-Output "</3"
}

AdmBorkBork

Posted 2015-09-15T15:10:44.523

Reputation: 41 581

3

C++, 210 193 184 168 bytes

In C++.. because.. Why not? :)

#include <iostream>
main(){auto&c=std::cout;srand(time(0));int i,j=3+rand()%18;while(i++<j)c<<"Loves me"<<(i%2?"":" not")<<(i==j?"":"...\n");c<<(j%2?"!\n<3":".\n</3");}

Live: 210 193 184 168

Just hope that any of my changes are not platform dependent.

Thanks to Ben Voigt for the help. Also, thanks to all the comments, they were very helpful.

wendelbsilva

Posted 2015-09-15T15:10:44.523

Reputation: 411

Humn.. just realize its 3 to 20. I will fix that later. Probably will add 2 more bytes... j=3+(int)(rand()*17.0/RAND_MAX) – wendelbsilva – 2015-09-15T19:33:04.623

You can save a lot by replacing #define c cout and using namespace std; by auto&c=std::cout; – Ben Voigt – 2015-09-15T22:55:23.197

Also save some with int i=0,j=rand()*20.0/RAND_MAX;while(i<j) – Ben Voigt – 2015-09-15T23:00:56.810

Hello, found a bug: Last line should be "Loves me!", not "Loves me." – MatthewRock – 2015-09-16T10:55:31.913

20.0 could be shortened to 20. or 20f. – Jens – 2015-09-16T11:34:33.410

Do you really need () around rand? – MatthewRock – 2015-09-16T14:11:32.160

You are correct. We dont need the ().. neither the {} in the while if we change the ;c<< to <<. I just found this nice article about random. To be [3,20] inclusive, I have to change to 18.f. Just found out that I could have used % instead of RAND_MAX... but if I change it now will look similar to tonysdg answer. Trying to see where else it can be optimized.

– wendelbsilva – 2015-09-16T14:27:17.907

1I'd say it's okay - C and C++ are similar. And right now this code is longer than Java... – MatthewRock – 2015-09-16T15:01:48.153

And actually you can just use time instead of srand and rand ;)

– MatthewRock – 2015-09-16T18:57:10.583

You can remove the space in #include <iostream>. @MatthewRock Longer than Java. wat. It's actually 9 bytes shorter... I knew it was impossible! – RK. – 2015-09-16T22:35:31.580

@RK. At the time of writing my comment, the code was longer than Java's. – MatthewRock – 2015-09-17T13:21:57.297

I do not understand how it can work without #include <time.h>... – Display_name – 2015-09-18T22:53:01.597

@GuillaumeLethuillier thats a good question. I didnt know for sure myself.. I had the idea it was included somewhere on ostream. Just google'd and looks like it's something like that, ctime is used for locale support

– wendelbsilva – 2015-09-18T23:57:21.867

3

Groovy, 110 bytes

A groovy kind of love:

int r=Math.random()*18;print((0..r+2).collect{"Loves me"+" not"*(it%2)}.join('...\n')+['!\n<3','.\n</3'][r%2])

Christoph Leuzinger

Posted 2015-09-15T15:10:44.523

Reputation: 31

2

Python 2, 117 bytes

from random import*
n=randint(3,20)
print"...\n".join("Loves me"+i%2*" not"for i in range(n))+[".\n</3","!\n<3"][n%2]

Observe that every Loves me( not)? is followed by ... and a newline, except for the last one. So this looks like a job for join.

DLosc

Posted 2015-09-15T15:10:44.523

Reputation: 21 213

A bit late but ".!\n\n<</33"[n%2::2] is 2 bytes shorter. – FryAmTheEggman – 2015-09-17T20:18:26.820

@FryAmTheEggman Yeah, I did see that but decided not to steal it from Loovjo. In the meantime, someone else has posted exactly that solution. [shrug] – DLosc – 2015-09-17T22:16:55.847

I hadn't noticed someone else posting it, but I am pretty sure my comment was the first that had it in it, so you can use it if you want :P

– FryAmTheEggman – 2015-09-17T22:27:08.677

2

R, 141 132 128 114 111 109 bytes

Code

k=sample(3:23,1);for(i in 1:k)cat("Loves",c("me not...\n","me...\n","me not.\n</3","me!\n<3")[1+i%%2+2*!i<k])

Ungolfed

k <- sample(3:23, 1)        # Generates random "k" number from 3 to 23
for(i in 1:k) {             # Loop this block increasing i from 1 until k by 1
  cat                       # Concatenate and paste everything inside this block
  ("Loves",                 # Push "Loves" on every iterations of the loop
      c(                    # Create a vector of strings
        "me not...\n",      # Push string to the index "1" of vector
        "me...\n",          #   to the index "2"
        "me not.\n</3",     #   to the index "3"
        "me!\n<3"           #   to the index "4"
        )[1+i%%2            # Subset the vector by the index (1 or 2)
          +2*!i<k])}        #   if final iteration of loop then index += 2 (3 or 4)

I've took some inspiration from Eric Brooks code.

Edit 1: Now the code correctly outputs the last punctuation as pointed out by Martin
Edit 2: Changed the for loop to a sapply and included the hearts inside the last line string.
Edit 3: Removed the {} and changed +(x==k)*2 to +2*!x<k
Edit 4: Back to for loop and removed the () from (i%%2)+1
Edit 5: Wrote me 4 times and removed the sep=""

Mutador

Posted 2015-09-15T15:10:44.523

Reputation: 1 361

1

Jelly, 55 bytes (non-competing?)

“¢zḞzƘFq»,;¥“ not”ṁ18X+2¤j“...¶”µċ⁷Ḃ©”/ẋ;3⁾¶<;®ị⁾.!¤;⁸;

Try it online!

As usual Jelly sucks with strings.

Erik the Outgolfer

Posted 2015-09-15T15:10:44.523

Reputation: 38 134

1

PowerShell, 85 88 bytes

+3 bytes thanks Veskah: That's a good point.

0..(1..19|Random)|%{($l='Loves me')+' not'*($n=$_%2)+'...'}
$l+('!
<3',' not.
</3')[!$n]

Try it online!

mazzy

Posted 2015-09-15T15:10:44.523

Reputation: 4 832

1This can generate "Loves me, Loves me not </3", which, based on how I read the specs, is below the minimum number of lines. – Veskah – 2019-03-06T14:36:51.100

Indeed of *3* to 20 lines inclusive. Thanks! – mazzy – 2019-03-06T15:48:26.690

1

R, 119 111 105 bytes

x<-sample(3:20,1);cat(rep(c("Loves me...\n","Loves me not...\n"),x)[1:x]);cat(ifelse(x%%2==1,"<3","</3"))

Edits 1,2: Coding the two options explicitly is saving space.

Eric Brooks

Posted 2015-09-15T15:10:44.523

Reputation: 293

1You can save a byte by using = for assignment rather than <- and another by doing x%%2>0 in place of x%%2==1. Also note that this doesn't handle the last line correctly; there should be a . or ! rather than .... (See example output in the question.) – Alex A. – 2015-09-15T20:43:43.193

1@Alex A. You don't need x%%2>0 either; just x%%2 – Flounderer – 2015-09-15T22:29:33.640

Good points, thanks. I need to go back and fix the ending – Eric Brooks – 2015-09-16T14:50:44.897

1

C 226 bytes

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void main(){srand(time(NULL));int i=rand()%18+3;int j;for(j=0;j<i;j++)printf("Loves me%s%s\n",(j%2)?" not":"",(j==i-1)?(j%2)?".":"!":"...");printf("<%s3\n",(j%2)?"":"/");}

(With formatting)

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

int main() {
    srand(time(NULL));
    int i = rand()%18 + 3;
    int j;
    for (j = 0; j < i; j++)
        printf("Loves me%s%s\n", (j % 2) ? " not" : "", (j==i-1) ? (j % 2) ? "." : "!" : "...");
    printf("<%s3\n", (j%2) ? "" : "/");
    return 0;
}

tonysdg

Posted 2015-09-15T15:10:44.523

Reputation: 141

1Remove return type from main (-5 bytes), make i and j global with default type (-8 bytes, -3 more because of default 0 in j), use 0 instead of NULL (-3). Other things - use only one variable and make the loop counting down maybe. Import stdio is not usually needed when golfing. – aragaer – 2015-09-16T10:15:30.313

1

mSL, 178 176 156 154 bytes

Edit 1: Changed == 0 to < 1
Edit 2: Removed unnecessary whitespace, thanks AlexA!
Edit 3: Removed parentheses

alias l {
var %n 1
while %n <= $rand(3,20) {
var %m $+(Love me,$iif($calc(%n % 2) < 1,$chr(32) $+ not),...)
echo %m
inc %n
}
echo $iif(n isin %m,</3,<3)
}

Denny

Posted 2015-09-15T15:10:44.523

Reputation: 31

1

Your solution is currently 176 bytes, not 177. Is all of the whitespace necessary? If not, you could shorten your code by a significant amount simply by removing unneeded whitespace.

– Alex A. – 2015-09-16T18:12:46.943

@AlexA. Oh don't know why I wrote 177, and thanks for pointing out the necessity of whitespace, it is indeed not needed! – Denny – 2015-09-16T22:45:33.697

1

Python 2, 115 bytes

from random import*
n=randint(2,20)
print'...\n'.join('Loves me'+i%2*' not'for i in range(n))+'.!\n\n<</33'[n%2::2]

SimonPJ

Posted 2015-09-15T15:10:44.523

Reputation: 141

1

Hassium, 265 Bytes

func main(){rnd=new Random();times=rnd.next(3,21);println("Loves me...");for(x=0;x<times-1;x++){if(x%2==0)println("Loves me not...");else println("Loves me...");}if((times-1)%2==0){println("Loves me not.");println("</3");}else{println("Loves me!");println("<3");}}

The answer has been golfed.

Jacob Misirian

Posted 2015-09-15T15:10:44.523

Reputation: 737

Your solution is currently 458 bytes, not 523. You can better your score by removing unnecessary whitespace and shortening variable names. See the other Hassium solution for examples.

– Alex A. – 2015-09-16T18:16:58.443

1As I noted on the other Hassium answer, the random number generator seems to be extremely biased. I ran this 500 times with the latest version and only got two </3. – Dennis – 2015-09-16T20:05:09.800

+Dennis The Random generator is built directly on top of the C# Random number generator. See: https://github.com/HassiumTeam/Hassium/blob/master/src/Hassium/HassiumObjects/Random/HassiumRandom.cs

– Jacob Misirian – 2015-09-16T21:19:05.477

3It doesn't seem to get seeded correctly. If I execute rnd = new Random();rnd.next(0,2); 1000 times, the distribution is OK. However, if I execute rnd = new Random(); once and rnd.next(0,2); 1000 times, I always get exactly 533 0s and 467 1s. – Dennis – 2015-09-16T21:53:56.563

1

PHP, 191 187 146 165 Bytes

$x=rand(5,22);for($i=2;++$i<=$x;){echo"\nLoves me";if($i%2<1)echo" not";if($i<$x)echo"...";if($i==$x&&$i%2<1){echo".\n</3\n";}elseif($i==$x&&$i%2>0){echo"!\n<3\n";}}

Ungolfed:

$x=rand(5,22);
for($i=2;++$i<=$x;){
    echo "\nLoves me";
    if($i%2<1) echo " not";
    if($i<$x) echo "...";
    if($i==$x && $i%2<1){
        echo ".\n</3\n";
    }
    elseif($i==$x && $i%2>0){
        echo "!\n<3\n";
    }
}

48,49 bytes for pyth and cjam ... wow :)

Marek Bettman

Posted 2015-09-15T15:10:44.523

Reputation: 111

Changed $i%2==0 to $i%2<1 (x2) and $i%2!=0 to $i%2>0 (x2) – Marek Bettman – 2015-09-16T21:48:10.993

turns out ternary operators are not the best answer at all times :) – Marek Bettman – 2015-09-16T22:02:46.677

1

Perl, 97 bytes

$_='She loves me...
'x(3+rand 18);s/(me.*?)me/$1me not/gs;s/e...
$/e!
<3/;s/t...
$/t.
<\/3/;print

Readable version:

$_="She loves me...\n"x(3+rand 18);
s/(me.*?)me/$1me not/gs;
s/e...$/e!\n<3/;
s/t...$/t.\n<\/3/;
print

bopjesvla

Posted 2015-09-15T15:10:44.523

Reputation: 283

1

C# (160)

The code is inspired by the answer from h.j.k., credit goes to him.

class P{static void Main(){for(int e=3+new Random().Next(0,18),i=0;++i<=e;)Console.WriteLine("Loves me"+(i%2>0?i<e?"...":"!\n<3":" not."+(i<e?"..":"\n</3")));}}

Ungolfed:

class P
{
    private static void Main()
    {
        for (int e = 3 + new Random().Next(0, 18), i = 0; ++i <= e;)
            Console.WriteLine("Loves me" + (i % 2 > 0 ? i < e ? "..." : "!\n<3" : " not." + (i < e ? ".." : "\n</3")));
    }
}

Abbas

Posted 2015-09-15T15:10:44.523

Reputation: 349

1

Lua, 137 132 bytes

Probably can be golfed a lot more, but here it is for now:

t=math.random(3,20)for i=1,t do io.write(i%2==0 and"Loves me"or"Loves me not")print(i==t and(i%2==0 and"!\n<3"or".\n</3")or"...")end

Code explanation and ungolfed:

t=math.random(3,20) --Generates a random number between 1 and 30. We need to assign it to a variable to check if the loop is over later.
for i=1,t do
  io.write(i%2==0 and"Loves me"or"Loves me not") --If i%2 is 0 write without a newline Loves me, if not print Loves me not.
  print(i==t and (i%2==0 and"!\n<3" or ".\n</3") or "...") --If it is not the end of the loop, put ..., else if we ended on an even print ! a newline, and then a heart, but if we ended on an odd put ., a newline and a broken heart :(
end

Edit: Chopped off some whitespace.

Nico A

Posted 2015-09-15T15:10:44.523

Reputation: 2 390

0

Japt, 77 76 bytes

Mq17 +3 o £`Lov ´{Y%2?" not":""}...`Ã
U· +`
Lov ´`+(UÊ%2?" not.
</3":"!
<3

Probably can be golfed a lot further.

Try it Online!

Embodiment of Ignorance

Posted 2015-09-15T15:10:44.523

Reputation: 7 014

0

1. Python 3, 179 171 167 bytes

from random import*;n=randint(3,20);s=""
for i in range(n):
    b=i%2==0;s+="Loves me"+(""if b else" not")
    if i<n-1:s+="...\n"
s+="!\n<3"if b else".\n</3";print(s)

Rene

Posted 2015-09-15T15:10:44.523

Reputation: 141

0

Hassium, 161 165 bytes

This answer is non-competing, since it requires a version of the interpreter that is newer than this challenge.

I golfed Reagan's answer.

func main()println(range(-1,t=new Random().next(3,21)).select(x=>"Loves me"+(x%2==0?" not":"")+(x==t-2?(x%2==0?".":"!"):"...")).join("\n"),"\n",t%2==0?"</3":"<3");

Unleashing the power of Hassium.

Ungolfed version

func main()
{
    t = new Random().next(3,21); # initialize the love number
    loveNumber = range(-1, t); # creates an array like this Array { -1 0 1 2 ... ... up to n } where n is a random number between 3 and 21 }
    loves = loveNumber.select(x => # iterates through the array
                                {
                                    ret = "Loves me";
                                    if (x % 2 == 0) # check if x is even
                                    {
                                        ret += " not"; # add ' not' to the result
                                    }
                                    ret += (x == t ? (x % 2 == 0 ? "." : "!") : "...");
                                    return ret;
                                }).join("\n"); # join the result with Unix newlines (\n)
    println(loves); # print it
    println(t%2==0?"</3":"<3");
}

zdimension

Posted 2015-09-15T15:10:44.523

Reputation: 119

3

On this site we typically only allow languages and features created prior to the posting of the challenge. In this case, it appears you added the range function to Hassium after the challenge was posted.

– Alex A. – 2015-09-16T18:31:40.703

Alex A., the range has always been in Hassium, I just forgot to put in the correct file so it wasn't usable. – zdimension – 2015-09-16T18:40:03.187

1>

  • If this particular code did not work with the interpreter that was available at the time this challenge was posted, your answer is technically invalid and should contain a disclaimer stating that it's non-competing. 2. The random number generator seems to be extremely biased. I ran this 500 times and only got two </3.
  • < – Dennis – 2015-09-16T19:51:58.153

    @Dennis however, if you got various lengths, I would say it's fine - I specified that any distribution is allowed - so although 2 in 500 isn't much, it's still acceptable, by the rules. – MatthewRock – 2015-09-17T09:39:23.370

    0

    ß, 138 bytes

    Works (with valid output). More a solution than the solution, could be golfed further:

    R=ß!G3,20,1)µL='Loves me'µD='...@LF@'µ€L&D)°/X=0°(R-1µ€L)°\mod(X,2)=0°{€' not')µ€D)°)€L)°\mod(R,2)°{µ€'!'&@LF&'<3')°]€' not.'&@LF&'</3')°}
    

    Sample:

    $ sharps "R=ß!G3,20,1)µL='Loves me'µD='...@LF@'µ€L&D)°/X=0°(R-1µ€L)°\mod(X,2)=0°{€' not')µ€D)°)€L)°\mod(R,2)°{µ€'!'&@LF&'<3')°]€' not.'&@LF&'</3')°}"
    Loves me...
    Loves me not...
    Loves me...
    Loves me not...
    Loves me...
    Loves me not...
    Loves me!
    <3
    

    mınxomaτ

    Posted 2015-09-15T15:10:44.523

    Reputation: 7 398