13
\$\begingroup\$

Sliding doors have varying prices based on the width of the doors. The different prices are as follows:

  • 60 - 80 cm: ¤150
  • 81 - 100 cm: ¤200
  • 101 - 120 cm: ¤220

When buying a closet you would obviously want to minimize the cost, so your task is to find the width of the doors that minimizes the total cost based on the total width of the closet.

Rules:

  • The total width will be taken as input
  • All doors will have the same width
  • Choose the smallest doors if two type of doors cost the same
  • The widths are in centimeters, integers not decimals
    • Round up decimals
  • The price shall be returned as an integer (no need for the currency sign)
  • The input and output formats are optional, but the order of the output must be: Number of doors, Width, Price.
  • Input will be in the range [120 1000).

This is code golf. Shortest code in bytes win.

Examples:

Input: 156
Output: 2, 78, 300

Input: 331
Output: 3, 111, 660

Input: 420
Output: 4, 105, 880
\$\endgroup\$
2
  • \$\begingroup\$ Width of 201 is an interesting test case... \$\endgroup\$ Feb 23, 2016 at 15:52
  • 8
    \$\begingroup\$ Sliding door? Clearly every door needs a @Doorknob. \$\endgroup\$
    – Alex A.
    Feb 23, 2016 at 17:06

7 Answers 7

4
\$\begingroup\$

JavaScript (ES6), 101 bytes

t=>[[80,150],[100,200],[120,220]].map(([w,p])=>[n=-~(~-t/w),-~(~-t/n),n*p]).sort((a,b)=>a[2]-b[2])[0]

-~(~-a/b) is the same as Math.ceil(a/b) in 31-bit integers.

\$\endgroup\$
4
\$\begingroup\$

Perl, 190 180 154 133 128 117 bytes

includes +1 for -p

use POSIX;$m=1E4;for$q(80,100,120){($m,@z)=($p,$n,ceil$_/$n)if$m>($p=(150,200,220)[$x++]*($n=ceil$_/$q))}$_="@z $m"

Commented:

use POSIX;                                  # for ceil()
$m = 1E4;                                   # init min price to 10k
for $q (80,100,120) {                       # iterate widths
    ($m,@z) = ($p,$n, ceil $_/$n)           # update min, output
    if $m > (                               #
       $p = (150,200,220)[$x++]             # grab price
          * ( $n = ceil $_/$q )             # times nr of doors needed
    )
}
$_="@z $m"

  • Save 11 bytes by inlining and splitting hash to two arrays

  • Save 5 bytes by using -p (thanks to @dev-null)

  • Save 18 bytes by using POSIX::ceil and 3 more by using list syntax for hash (thanks to @msh210)

\$\endgroup\$
6
  • \$\begingroup\$ Shorter than sub r{$a=$_[0];~~$a==$a?$a:1+~~$a} is sub r{use POSIX;ceil pop}. \$\endgroup\$
    – msh210
    Feb 23, 2016 at 20:47
  • \$\begingroup\$ Shorter than (80=>150,100=>200,120=>220) is (80,150,100,200,120,220). \$\endgroup\$
    – msh210
    Feb 23, 2016 at 20:49
  • \$\begingroup\$ Does this work for very very wide doors (where the price is more than 10_000)? \$\endgroup\$
    – msh210
    Feb 23, 2016 at 20:52
  • \$\begingroup\$ @msh210 Thanks for the tips, I'll incorporate them! No, it only works for the range specified in the question [120-1000), but one can always change 1E4 to 1E9... \$\endgroup\$
    – Kenney
    Feb 23, 2016 at 21:35
  • \$\begingroup\$ Oh, I didn't notice that the question had specified a range. \$\endgroup\$
    – msh210
    Feb 23, 2016 at 22:07
3
\$\begingroup\$

PowerShell, 137 135 bytes

param($a)$j=9e9;60..120|%{if((($c=[math]::ceiling($a/$_))*($p=(220,(200,150)[$_-le80])[$_-le100]))-lt$j){$j=($k=$c)*$p;$i=$_}}
$k;$i;$j

Output is newline-separated.

We take input $a, set our cost $j to 9000000000 (a large number that's way more than we would ever need). Next, we loop from 60..120 with |%{...}. Each iteration we calculate the $p price of the current item with a pseudo-ternary statement, then calculate the $c ceiling of $a/$_. If the current total is smaller than the smallest total we've seen ($j), save all these variables: $j (the total), $k (the number of doors required), and $i (the door width), and continue the loop. Once the loop is finished, just output the best values.

Edit -- Saved two bytes by moving the $c and $p assignments into the if conditional

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 47 bytes

Code:

D120/ó>DU=/ó>=D101›iX220*=q}D80›iX200*=q}X150*=

Not the best submission, but at least something :)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Putting 333 into the TIO gives an output of [3, 112, 660] when (afaik) the output should be [3, 111, 660] since 3*111 equals 333 perfectly \$\endgroup\$
    – Helen
    Aug 8, 2018 at 20:14
  • \$\begingroup\$ Similar problem with 201 giving [2, 101, 400] instead of [2, 101, 440] \$\endgroup\$
    – Helen
    Aug 8, 2018 at 20:17
2
\$\begingroup\$

Pyth, 65 bytes

ho+eNcehNTm[d*hd?>81ed150?<101ed220 200)f}eTr60 121m[d.EcQd)r2 17

Try it here!

Explanation

First this generates a list of all possible door count/door width combinations and calculates the price for every of those combinations. Then we only have to order it by price and door width and take the first element of the resulting list.

Code explanation follows after I golfed this down Please help me golf this, this is way too long.

ho+eNcehNTm[d*hd?>81ed150?<101ed220 200)f}eTr60 121m[d.EcQd)r2 17  # Q=input

                                                   m        r2 17  # map range(2,17) to
                                                    [d     )       # list with door count first
                                                      .EcQd        # and width second
                                        f                          # Filter map result with T
                                         }   r60 121               # in range(60,121)
                                          eT                       # door width
          m                                                        # map filter result with d
           [d                          )                           # to a list with door count and width first
             *hd                                                   # mult door count with
                ?>81ed150?<101ed220 200                            # price per door, simple lookup with ternaries
 o                                                                 # order map result with N
  +eNcehNT                                                         # order key=price+width/10
h                                                                  # first element is the best
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6) 96

n=>[80,100,120].map((d,i)=>[d=-~(~-n/d),-~(~-n/d),d*[150,200,220][i]]).sort((a,b)=>a[2]-b[2])[0]

As noted by @Neil, =-~(~-n/d) is equivalent to division with rounding up for integeres of 32 bit or less.

\$\endgroup\$
1
\$\begingroup\$

R, 135 104 bytes

"!"=utf8ToInt;cbind(n<-16:1,w<-ceiling(scan()/n),p<-n*approx(!"<Qex",!"–ÈÜÜ",w,"c")$y)[order(p)[1],]

Try it online!

Saved 31 bytes by

  • decompressing numbers
  • using utf8ToInt
  • using "!" to shorten function call
  • using vectorized functions
  • not defining total length
  • using cbind directly rather than after defining variables

How it works:

  1. approx returns the price of a single door based on its length. It returns NA outside of the range [60,120].
  2. Based on the spec, the total numbers of doors can't be more than 16 (total length 1000). All number of doors from 16 to 1 are tested, and the triplet (number of doors, door width, total price) is returned.
  3. The order function is used to locate the minimum price; the correct triplet is extracted based on that. In case of ties, order will return the entry that comes first, and since we looped from 16 to 1 the greatest numbers of doors (smallest door width) will be returned.
\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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