2
\$\begingroup\$

There is a helicopter flying 500 meters from the ground. It can fly up 100 meters, which takes 1.0 secs. Or if it doesn't fly up it will fall 200 meters, which also takes 1.0 secs - This means if the instruction is anything other than "Fly" the helicopter falls. Build a program that takes input of a list of instructions, telling the helicopter when to fly and when not to. When the helicopter falls it should output the time counter.

INPUT:

Fly Dance Fly Golf Fly Fly

OUTPUT:

8.5 secs

Walkthrough:

1) Fly == Fly so +100 = 600m

2) Dance != Fly so -200 = 400m

3) Fly == Fly so +100 = 500m

4) Golf != Fly so -200m = 300m

5) Fly == Fly so +100 = 400m

6) Fly == Fly so +100 = 500m

7) NO INSTRUCTIONS so -200 = 300m

8) NO INSTRUCTIONS so -200 = 100m

9) NO INSTRUCTIONS so -100 = 0m (This takes 0.5 seconds)

Each instruction should be separated by a space, and if the instuction isn't fly, then automatically fall. When the program runs out of instructions automatically fall. Your program must output in (float)secs, and if it takes => 60.0 seconds display in mins and seconds eg. 1 mins 32.0 secs

Seconds are float decimal values, minutes are whole interger values. Also note capitalization does not matter your program should work for capitals or no capitals.

This is code-golf so the least NO bytes wins!

\$\endgroup\$
  • 3
    \$\begingroup\$ Could you clarify this? Perhaps a step by step walk through of the example. Is the word "fall" being used both for dropping 200 meters, and for reaching 0 meters? Perhaps using a different word for reaching 0 meters would make this clearer. Is the output the time when the helicopter reaches 0 meters? \$\endgroup\$ – trichoplax Nov 15 '16 at 18:47
  • 2
    \$\begingroup\$ Can we assume that if the helicopter is at 100m, and falls, it still takes 1 second to reach 0m, even though it usually takes 1 second to drop by 200m? \$\endgroup\$ – trichoplax Nov 15 '16 at 18:57
  • 6
    \$\begingroup\$ I think this could be a good question is it is asked more clearly maybe with some examples. May I suggest the Sandbox to get some feedback prior to posting next time? \$\endgroup\$ – ElPedro Nov 15 '16 at 18:59
  • 2
    \$\begingroup\$ if it dosen't fly up, it will fall 200m does that mean heli can crash and after crashing it should not fly anymore which means rest of the instructions should be ignored? Example : please tell me output if the input is this : fly fall fall fall fall fly fly fly fly \$\endgroup\$ – Mukul Kumar Nov 15 '16 at 19:26
  • 2
    \$\begingroup\$ The string "M min S secs" specifically, or are normal output formats like a list of [M,S] and other reasonable formats like "M:S" OK? If specifically, then can less than one minute output "0 min S secs"? \$\endgroup\$ – Jonathan Allan Nov 15 '16 at 19:53

12 Answers 12

3
\$\begingroup\$

Python, 100 92 89 bytes

lambda I:sum(reduce(lambda(a,s),i:(a+(a>0)*(-1,.5)[i=='Fly'],s+(a>0)),I.split(),(2.5,0)))

try it online

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This doesn't output minutes though. \$\endgroup\$ – Andriy Makukha Jun 26 at 5:39
3
\$\begingroup\$

05AB1E, 31 bytes

l#ā«'¤†Q3*Í5šηO.γd}нRć;sg+60‰0Û

Follows the challenge to the letter. Input as a space-delimited string, and output as a list [sec] or [min,sec], where sec is a float and the potential min is an integer.

If taking the input as a list of strings is allowed, the # could be removed.
If outputting as [min,sec] even if min is 0 is allowed, the tailing can be removed.

Try it online or verify a few more test cases.

Explanation:

l                             # Convert the (implicit) input-string to lowercase
                              #  i.e. "Fly Dance Fly Golf FLY fLy"
                              #   → "fly dance fly golf fly fly"
 #                            # Split it on spaces
                              #  → ["fly","dance","fly","golf","fly","fly"]
  ā                           # Push a list in the range [1, length]
                              # (without popping the list itself)
                              #  → [1,2,3,4,5,6]
   «                          # Merge it to the list of words
                              #  → ["fly","dance","fly","golf","fly","fly",1,2,3,4,5,6]
    '¤†                      '# Push dictionary string "fly"
       Q                      # Check for each word (or integer) if it's equal to "fly"
                              # (1 if truthy; 0 if falsey)
                              #  → [1,0,1,0,1,1,0,0,0,0,0,0]
        3*                    # Multiply each by 3
                              #  → [3,0,3,0,3,3,0,0,0,0,0,0]
          Í                   # Decrease each by 2 (so 1 if truthy; -2 if falsey)
                              #  → [1,-2,1,-2,1,1,-2,-2,-2,-2,-2,-2]
           5š                 # Prepend a 5 to this list
                              #  → [5,1,-2,1,-2,1,1,-2,-2,-2,-2,-2,-2]
             η                # Get all prefixes of this list
                              #  → [[5],[5,1],...[[5,1,-2,1,-2,1,1,-2,-2,-2,-2,-2,-2]]
              O               # Sum each prefix
                              #  → [5,6,4,5,3,4,5,3,1,-1,-3,-5,-7]
               .γ }           # Consecutive group the values by:
                 d            #  Where the value is >= 0
                              #   → [[5,6,4,5,3,4,5,3,1],[-1,-3,-5,-7]]
                }н            # After the group-by, only leave the first group
                              #  → [5,6,4,5,3,4,5,3,1]
                  Rć          # Reverse and extract the head,
                              # so we've extracted the last item loose to the stack
                              #  → [3,5,4,3,5,4,6,5] and 1
                    ;         # Halve that last item
                              #  → [3,5,4,3,5,4,6,5] and 0.5
                     sg       # Swap to get the list, and pop and push its length
                              #  → 8
                       +      # Add it to the halved last item
                              #  → 8.5
                        60‰   # Take the divmod-60
                              #  → [0,8.5]
                           0Û # And remove a potential leading 0
                              #  → [8.5]
                              # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why '¤† is "fly".

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Perl, 90 bytes

$a=5;
$_++,$a+=shift=~/Fly/?1:-2 while$a;
$==$_/60;
$_%=60;
say+($=?"$= mins ":"")."$_ secs"

Accepts input as command-line parameters. Run as

perl -E '$a=5;$_++,$a+=shift=~/Fly/?1:-2 while$a>0;$==$_/60;$_%=60;say+($=?"$= mins ":" ")."$_ secs"' Fly Dance Fly Fly Golf

Starts $a at 5, and increases it by 1 every time it finds "Fly", decrements by 2 otherwise. Keeps going until $a is non-positive, and counts how many iterations it took to get there. $= is special and forces its value to be an integer, so $==$_/60 only takes the integer portion of the division, ignoring the rest. Everything else is self-explanatory, I feel.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Burlesque, 64 bytes

wdm{"Fly"=={1}{-2}IE}@5+]q++pa{0.>}TWsa-.j[~2./.+J60./foJ60.*j.-

Try it online!

wd         # Split into words
m{         # Map
 "Fly"==   # word is "Fly"?
 {1}{-2}IE # If fly 1 else -2
}
@5+]       # Prepend 5.0
q++pa      # Calculate partial sums
{0.>}TW    # Take until 0 or less
sa-.       # Length of this -1 (to account for pushed 5.0)
j[~2./     # Take the remaining height /2
.+         # Add this time 
############ Mins Secs ##############
J60./fo    # Calc number of mins 
J60.*      # N mins * 60
j.-        # Calc seconds over

If we don't have to deal with the mins/secs rule:

Burlesque, 49 bytes

wdm{"Fly"=={1}{-2}IE}@5+]q++pa{0.>}TWsa-.j[~2./.+

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Incorrect. Consider case Eat Play Love Fly Fly Fly Fly Fly Fly. Correct answer is 2.5. \$\endgroup\$ – Andriy Makukha Jun 26 at 5:50
2
\$\begingroup\$

C 93

Thanks to @ceilingcat for finding a much shorter version

i,h=5;main(c,v)int**v;{for(;h>0;)h+=*v[(++i<c)*i]-'ylF'?-2:1;printf("%f secs\n",i-(h<0)*.5);}

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PHP, 55 54 bytes

for($h=5;$h>0;)$h+='Fly'==$argv[++$i]?:-2;echo$h/2+$i;

Loops through command line arguments; run with -r.

Height is divided by 100 to simplify output and calculation: If height is below zero (i.e. -100m),
adding half of it (-50 divided by 100: -.5) to the time removes half a second from the result.

That combined with the magic of Elvis golfed 5 6 bytes from my initial program.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Mathematica 211 bytes

(s=ToString;t=Length[#[[;;(FirstPosition[#,x_/;x<=0,1]-1/. 0->Length@#)]]]&[x=500+Accumulate[If[#=="Fly",100,-200]&/@(StringSplit@#)]];
If[#>=60,s@Floor[#/60]~~" min ",""]~~s@Mod[#,60]~~ " sec"&[t+x[[t]]/200.])&

This algorithm assumes the flight ends when the altitude reaches 0 for the first time. Looking at some of the other answers, I think people have the helicopter flying below ground level. I don't allow "touch and go" either.

Ungolfed:

in="Fly Dance Fly Golf Fly Fly";
s=ToString;StringSplit@in
If[#=="Fly",100,-200]&/@%
altList=500+Accumulate@%
l=Length@altList
(* find last positive before first nonpositive *)
FirstPosition[altList,x_/;x<=0,1]-1
t=Length[altList[[;;(%/. 0->l)]]]
t+altList[[t]]/200.
If[%>=60,s@Floor[%/60]~~" min ",""]~~s@Mod[%,60]~~ " sec"
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Javascript, 137

a=>{for(s=5,i=0,a=a.toLowerCase().split(" ");s>=0;){s+=a[i]&&a[i++]=="fly"?1:-2}return parseInt(i/60)+"min "+(i%60+s/2).toFixed(1)+"sec"}

Try it online!

Test:

"Fly fly fly fly fly fly fly fly hi test flu fly fly Fly fly fly fly fly flu flu FLY fly fly Fly fly fly fly fly fly fly fly dance again now fly fly fly fly fLy fly fly flu flu fly Fly fly flY flY fly fly fly fly go flu flu fly fly fly fly fly fly fly win flu fly "

Result:

1min 17.5sec
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

APL (Dyalog Classic), 80 bytes

Caveat: case sensitive.

This will return (minutes, seconds) if the flight takes more than 59 seconds, otherwise – only seconds.

{(1+⍵≥60)⌷⍵(⍵(⌊÷,⊢|⊣)60)},{(⍵⍳0)⌊¯0.5+⍵⍳¯1}{5++\¯2@~(4×≢⍵)↑{⍵≡'Fly'}¨' '(≠⊆⊢),⍵}

Try it online!

Without conversion to minutes it's 54 bytes:

{(⍵⍳0)⌊¯0.5+⍵⍳¯1}{5++\¯2@~(4×≢⍵)↑{⍵≡'Fly'}¨' '(≠⊆⊢),⍵}
| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

Scala, 88 bytes

s=>{val n=s.split(" ").count("Fly"==)*1.5+2.5
(if(n<60)""else n/60+"min ")+n%60+" secs"}

Ungolfed:

s=>{
  val n=s.split(" ").count("Fly"==)*1.5+2.5
  (
    if(n<60)
      ""
    else
      (n/60)+"min "
  )
  +(n%60)
  +" secs"
}

Uses the same formula as Copper's python answer.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ It's incorrect. Consider the test case Eat Play Love Fly Fly Fly Fly Fly Fly. Correct answer is 2.5. \$\endgroup\$ – Andriy Makukha Jun 26 at 5:46
-1
\$\begingroup\$

Python 2, 85 91 bytes

t=2.5+input().upper().split().count('FLY')*1.5
print('%d mins'%(t/60))*(t>59),`t%60`,'secs'

Takes input on STDIN, surrounded by quotes (single or double). Simply counts the number of Flys there are in the input, performs some path to calculate the number of seconds, then formats it.

Now case-insensitive!

Fixed a bug with the same bytecount thanks to Jonathan Allan!

Saved 2 bytes thanks to Shebang!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Bit of a nitpick, but "Marty McFly went to the future" would print 4.0 secs rather than 2.5 secs. Fixable for one byte with t=(5+input().split().count('Fly')*3)/2. \$\endgroup\$ – Jonathan Allan Nov 17 '16 at 6:26
  • 1
    \$\begingroup\$ ...but you can golf that cost off with t=2.5+input().split().count('Fly')*1.5. \$\endgroup\$ – Jonathan Allan Nov 17 '16 at 6:29
  • 1
    \$\begingroup\$ Since I don't think leading spaces matter, this print statement should work: print('%d mins'%(t/60))*(t>59),``t%60``,'secs' (replace double ticks with single ticks). It only has a leading space if t < 60. \$\endgroup\$ – Kade Nov 18 '16 at 17:26
  • \$\begingroup\$ Also this would return a float for the minutes if it's a float above 60, i.e. 80.5 secs -> 1.3416666 minutes. \$\endgroup\$ – Kade Nov 18 '16 at 17:44
  • \$\begingroup\$ @Shebang It doesn't return a float for the minutes. The %d implicitly casts to an int -- ideone.com/JKOS0H. Thanks for the tip though! \$\endgroup\$ – Copper Nov 18 '16 at 18:54
-1
\$\begingroup\$

AWK, 150 bytes

Below is a rather straightforward implementation in AWK, the nice thing about it is that you can run it interactively and feed it by typing commands by hand (just don't forget to remove RS=" ", if you want one command per line).

Golfed

awk 'BEGIN{RS=" ";h=500;t=0}toupper($0)~/FLY/{h+=100;t+=1;next}{h-=200;t+=1;}END{t+=h/200;F=(t>59?"%d mins ":"%.0d") "%.1f secs";printf F,t/60,t%60;}'

Test

echo "Fly Dance FLy Golf Fly Fly" |\
awk 'BEGIN{RS=" ";h=500;t=0}toupper($0)~/FLY/{h+=100;t+=1;next}{h-=200;t+=1;}END{t+=h/200;F=(t>59?"%d mins ":"%.0d") "%.1f secs";printf F,t/60,t%60;}'

8.5 secs
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Incorrect. Consider case Eat Play Love Fly Fly Fly Fly Fly Fly. Correct answer is 2.5 sec. \$\endgroup\$ – Andriy Makukha Jun 26 at 5:30

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