Let's learn some soil pH chemistry!

14

3

Andrew is a chemist, interested in the acidity of solutions and in agriculture. After months of research (Google is not his friend), he came up with the following table* regarding the human-readable level of acidity in terms of the pH (potential of Hydrogen):

         Denomination        |         pH range
                             |
    -------------------------+-----------------------------   
    Ultra acidic             |          below 3.5
    -------------------------+------------------------------
    Extremely acidic         |    between 3.5 and 4.4
    -------------------------+------------------------------
    Very strongly acidic     |    between 4.5 and 5.0
    -------------------------+------------------------------
    Strongly acidic          |    between 5.1 and 5.5
    -------------------------+------------------------------
    Moderately acidic        |    between 5.6 and 6.0
    -------------------------+------------------------------
    Slightly acidic          |    between 6.1 and 6.5
    -------------------------+------------------------------
    Neutral                  |    between 6.6 and 7.3
    -------------------------+------------------------------
    Slightly alkaline        |    between 7.4 and 7.8
    -------------------------+------------------------------
    Moderately alkaline      |    between 7.9 and 8.4
    -------------------------+------------------------------
    Strongly alkaline        |    between 8.5 and 9.0
    -------------------------+------------------------------
    Very strongly alkaline   |          over 9.0

Given a non-negative decimal number representing the pH of a substance, output its Denomination. You can take input and provide output by any standard method. The data types you are allowed to take input with are:

  • Float
  • Double
  • Your language's standard decimal number data type
  • String

And you must output a String representing the denomination. Built-ins related to chemistry are forbidden (Sorry, Mathematica!).

Approximation Rule: If the pH you receive is between an upper bound of a denomination and the lower bound of the next one (e.g. between 7.8 and 7.9), it gets approximated to the closest value between the two: if the pH ≥ upperBound of the first + 0.5, then it should receive the second denomination, but if the pH < upperBound of the first + 0.5, then it should receive the first one (e.g 7.85 is approximated to 7.9, but 7.84999 is approximated to 7.8). See the test cases for clarifications.

Test Cases:

Input ->  Output

6.40  ->  Slightly acidic
8.399 ->  Moderately alkaline
3.876 ->  Extremely acidic
10.60 ->  Very strongly alkaline     
0.012 ->  Ultra acidic
7.30  ->  Neutral
7.85  ->  Moderately alkaline (the approximation rule is applied)
7.849 ->  Slightly alkaline (the approximation rule is applied)
6.55  ->  Neutral (the approximation rule is applied)

This is , so the shortest valid submission (in bytes) wins!

*Andrew did not come up with that, it was Wikipedia!

Mr. Xcoder

Posted 2017-06-19T10:14:10.323

Reputation: 39 774

Sandbox for those who can see deleted posts. – Mr. Xcoder – 2017-06-19T10:17:17.927

yeah this doesn't really work with actual acidity levels. anything more acidic than lemon juice is ultra acidic – Destructible Lemon – 2017-06-19T10:22:51.340

@DestructibleLemon If lemon juice is Ultra acidic, then Fluoroantimonic acid, that behaves like having −31.3 is a total atomic bomb :))

– Mr. Xcoder – 2017-06-19T10:26:01.967

oh, I see where you went wrong. 3.5 ph is not ultra acidic, but it is ultra acidic if the soil you are growing plants in is 3.5 ph. what I mean is, this table refers to soil ph – Destructible Lemon – 2017-06-19T10:46:12.353

@DestructibleLemon That's what this challenge is about: soil pH :)... This is totally what I intended :§ – Mr. Xcoder – 2017-06-19T10:56:52.960

1Brownie points for an answer in Python or Swift :) – Mr. Xcoder – 2017-06-19T12:25:29.900

How isn't [tag:kolmogorov-complexity] suited for this? You must compress the denomination strings... – Mr. Xcoder – 2017-06-19T13:15:11.173

@Mr.Xcoder if the problem were to print the table, that would be a kolmogorov-complexity problem. But since the problem is to take a number as input and return a string, this is not a kolmogorov-complexity problem (I could be wrong about this, but that's the answer I got on one of my past posts) – musicman523 – 2017-06-19T13:24:09.317

@musicman523 Ok, I was really confused – Mr. Xcoder – 2017-06-19T13:24:47.337

Can you add 3.49 and 9.01 as test cases as the outer limits are differents from the inner ones – ovs – 2017-06-19T16:42:49.870

Is the input restricted to being a valid value of "your language's standard decimal number data type"? – user253751 – 2017-06-20T00:00:27.203

IMHO there should be a category, like "mapping", for this kind of challenge. It's basically "map elements in this specific set onto this other set". – Steve Bennett – 2017-06-20T01:02:21.450

@immibis Yes, you are guaranteed that the value is valid – Mr. Xcoder – 2017-06-20T07:15:07.503

@Mr.Xcoder So if I use Boolfuck again, where the standard data type is a bit, the input can only be 0 or 1 (decimal)? – user253751 – 2017-06-20T07:44:03.937

@immibis I really do not know what to say about this, but I will allow it. – Mr. Xcoder – 2017-06-20T07:45:19.040

I feel like it should be natural logarithm of hydronium.... – bleh – 2017-06-21T02:27:10.500

Answers

6

Jelly,  77 73  71 bytes

“£RĿÐƭðṚ°ƲṂṾẒ=ʂXḣsịɠ<»Ḳµ,Ṛ;€"“¡D⁺“a&»j“¿<z»W¤ṙ3
×20<“FYeoy³ƓɗʋṆ‘Sị¢⁾. y

A monadic link taking the number and returning a list of characters; or a full program printing the result.

Try it online!

How?

“ ... »Ḳµ,Ṛ;€"“¡D⁺“a&»j“¿<z»W¤ṙ3 - Link 1, name list: no arguments
“ ... »                          - compression of "Ultra Extremely Very.strongly Strongly Moderately Slightly"
       Ḳ                         - split at spaces
        µ                        - monadic chain separation, call that adjectives
          Ṛ                      - reverse adjectives
         ,                       - pair these two lists
              “¡D⁺“a&»           - compression of [" alkaline"," acidic"]
             "                   - zip with:
           ;€                    -   concatenate for €ach
                             ¤   - nilad followed by links as a nilad
                       “¿<z»     -   compression of "Neutral"
                            W    -   wrap in a list
                      j          - join
                              ṙ3 - rotate left by 3: ["Strongly alkaline","Moderately alkaline","Slightly alkaline","Neutral","Slightly acidic","Moderately acidic","Strongly acidic","Very.strongly acidic","Extremely acidic","Ultra acidic","Ultra alkaline","Extremely alkaline","Very.strongly alkaline"]

×20<“FYeoy³ƓɗʋṆ‘Sị¢⁾. y - Main link: number, pH
×20                     - multiply by 20
    “FYeqy³ƓɗʋṆ‘        - code-page indexes = [70,89,101,111,121,131,147,157,169,180]
   <                    - less than? (vectorises)
                        -   i.e.: pH < [3.5,4.45,5.05,5.55,6.05,6.55,7.35,7.85,8.45,9]
                S       - sum
                  ¢     - call last link (1) as a nilad
                 ị      - index into (1-indexed and modular)
                        - ...note that the sum is never 11 or 12, so "Ultra alkaline" and
                        -    "Extremely alkaline" wont be fetched, but that a sum of 0
                        -    fetches "Very.strongly alkaline", as required.
                   ⁾.   - literal list of characters ['.', ' ']
                      y - translate (replace any '.' with a ' ' i.e. for "Very.strongly")
                        - if running as a full program, implicit print

Jonathan Allan

Posted 2017-06-19T10:14:10.323

Reputation: 67 804

I always enjoy competition between 05AB1E and Jelly... Only 2 bytes away – Mr. Xcoder – 2017-06-19T11:42:45.883

3Jelly beats 05AB1E?!?! – Erik the Outgolfer – 2017-06-19T11:43:10.227

5

PHP, 199 bytes

foreach([35,9.5,6,5,5,5,8,5,6,5.5]as$l)$p+=$argn*10>=$s+=$l;$p-=$argn==9;echo[Ultra,Extremely,"Very strongly",Strongly,Moderately,Slightly][$p>6?12-$p:$p],[" acidic",Neutral," alkaline"][1+($p<=>6)];

Try it online!

Jörg Hülsermann

Posted 2017-06-19T10:14:10.323

Reputation: 13 026

4

C# (.NET Core), 236 bytes

p=>{var l=new[]{70,89,101,111,121,131,147,157,169,180,280};var a="Ultra,Extremely,Very strongly,Strongly,Moderately,Slighty, acidic,Neutral, alkaline".Split(',');int i=0;for(;p*20>=l[i];i++);return i==6?a[7]:i<6?a[i]+a[6]:a[12-i]+a[8];}

Try it online!

This solution considers that p cannot be greater than 14.

Charlie

Posted 2017-06-19T10:14:10.323

Reputation: 11 448

4

T-SQL, 305 299 bytes

DECLARE @ char(999)=REPLACE(REPLACE(REPLACE(REPLACE('SELECT TOP 1i FROM(VALUES(''Very s$#9&S$#8.4&Moderately#7.8&Slightly#7.3&Neutral'',6.5&Slightly@6&Moderately@5.5&S$@5&Very s$@4.4&Extremely@3.4&Ultra@-1))x(i,j),t WHERE j<a','#',' alkaline'','),'@',' acidic'','),'&','),('''),'$','trongly')EXEC(@)

Input is via a pre-existing table t with DECIMAL(4,1) column a, per our Input/Output rules.

Because of the DECIMAL(4,1) data type, any "approximation rule" rounding takes place when the value is entered into the input table, so doesn't need to be explicitly managed by my code.

After the space-saving REPLACES are performed, this is a simple SQL query joining our input table with our list of values:

SELECT TOP 1 i
FROM(VALUES
    ('Very strongly alkaline',9),
    ('Strongly alkaline',8.4),
    ('Moderately alkaline',7.8),
    ('Slightly alkaline',7.3),
    ('Neutral',6.5),
    ('Slightly acidic',6),
    ('Moderately acidic',5.5),
    ('Strongly acidic',5),
    ('Very strongly acidic',4.4),
    ('Extremely acidic',3.4),
    ('Ultra acidic',-1)
) x(i,j), t
WHERE j<a

I reverse the order so TOP 1 picks the first one less than our input value.

Even this form (after removing line breaks and extra spaces) is pretty good, at 318 bytes. Adding the overhead of the DECLARE, REPLACES AND EXEC only becomes worth it with all the repeated phrases.

EDIT: Save 6 bytes by removing unnecessary ".0" on several values

BradC

Posted 2017-06-19T10:14:10.323

Reputation: 6 099

3

05AB1E, 81 80 79 77 76 74 bytes

'Ĉ“¢³¿™ly³¾‚Òw““³¾§ÓªÅ“«#¦¦’šÉaƒ£’«Š’w¡Îic’«)˜™'wð:I•t{~À•ST+.¥70+20/‹Oè

Try it online!

Test suite

Explanation

'Ĉ                   # push the string "neutral"
“¢³¿™ly³¾‚Òw“         # push the string "slightly moderately strongly veryw"
“³¾§ÓªÅ“              # push the string "strongly extremely ultra"
«                     # concatenate the top 2 items on the stack
 #                    # split on spaces
  Â                   # push a reversed copy
   ¦¦                 # remove the first 2 elements of the copy ("ultra", "extremely")
’šÉaƒ£’«              # append the string "walkaline" to each ("walk"+"a"+"line")
        Š             # move down 2 places on the stack
’w¡Îic’«              # append the string "wacidic" to each ("w"+"acid"+"ic")
        )˜            # wrap stack in a list and flatten
          ™           # title case each
           'wð:       # replace each instance of "w" with a space
I                     # push input
 •t{~À•               # push the base 255 compressed number 920006021
       ST+            # split to list of digits and add 10 to each
          .¥          # undelta (compute increments from 0)
            70+       # add 70 to each
               20/    # divide each by 20
                  ‹   # compute input less than for each
                   O  # sum
                    è # use this to index into list of strings

Emigna

Posted 2017-06-19T10:14:10.323

Reputation: 50 798

This is surprisingly long for 05AB1E – Mr. Xcoder – 2017-06-19T11:11:58.190

Late to the party, but still curious: does anyone directly program in this language (even if only for code golfing) or is this the output of some sort of a "compiler" ? – avl42 – 2017-06-20T07:52:51.300

1@avl42: We code directly in this language yes (generally only for golfing of course). I'd hate to see someone use this in production code ;) It is an interpreted language so code you write in this language gets interpreted to python code. – Emigna – 2017-06-20T08:24:26.410

1@Emigna I'd say "translated" rather than "interpreted" (it's kind of opposite meaning) – anatolyg – 2017-06-20T09:44:38.913

@anatolyg: Yes, you are correct there. I always think interpreted for some reason, probably due to python. It is translated into an interpreted language :) – Emigna – 2017-06-20T09:48:54.890

Would have been better for my sanity, if the line noise were the result of some translation, not the outset ;-) – avl42 – 2017-06-21T15:17:52.940

2

Retina, 228 bytes

$
.00
\.(.)\.?(.).*
$1$2
.+
$*
1{900,}
VA
1{845,}
STA
1{785,}
MA
1{735,}
SLA
1{655,}
Neutral
1$
1 acidic
1{605,}
SL
1{555,}
M
1{505,}
ST
1{445,}
V
1{350,}
Extremely
1+
Ultra
M
Moderately
V
Very sT
T
trongly
L
lightly
A
 alkaline

Try it online! Link includes test suite. Explanation:

$
.00
\.(.)\.?(.).*
$1$2

Multiply the input by 100 by suffixing a spare decimal point and two zeros then deleting the decimal point and all but two digits after it.

.+
$*

Convert to unary.

1{900,}
VA
1{845,}
STA
1{785,}
MA
1{735,}
SLA

Handle all the alkalis, converting into abbreviations that will be expanded later.

1{655,}
Neutral

Handle neutral.

1$
1 acidic

Anything left must be acidic. (But leave the 1 in case the pH is 0.001)

1{605,}
SL
1{555,}
M
1{505,}
ST
1{445,}
V
1{350,}
Extremely
1+
Ultra

Handle all the acids.

M
Moderately
V
Very sT
T
trongly
L
lightly
A
 alkaline

Expand the abbreviations.

Neil

Posted 2017-06-19T10:14:10.323

Reputation: 95 035

Wow, I think it took a while to golf it down... – Mr. Xcoder – 2017-06-19T12:53:44.047

2

Python 2, 202 bytes

-15 bytes thanks to @JonathanAllan

lambda k:'Neutral_Slightly_Moderately_Strongly_Very strongly_Extremely_Ultra'.split('_')[abs(sum(round(k*10)>ord(i)for i in'",27<AINT')+(k>9)-(3.45<k<3.5)-6)]+(' acidic'*(k<6.55)or' alkaline'*(k>=7.35))

Try it online!

ovs

Posted 2017-06-19T10:14:10.323

Reputation: 21 408

2You took my brownie points. – Mr. Xcoder – 2017-06-19T14:13:29.320

2

JavaScript (ES6), 192 189 185 184 bytes

k=>([...'09544474540'].some(n=>(i--,k-=++n)<0,i=7,k=k*10-33.5),'Neutral,Slightly,Moderately,Strongly,Very strongly,Extremely,Ultra'.split`,`[i<0?-i:i]+(i?i>0?' acidic':' alkaline':''))

Test cases

let f =

k=>([...'09544474540'].some(n=>(i--,k-=++n)<0,i=7,k=k*10-33.5),'Neutral,Slightly,Moderately,Strongly,Very strongly,Extremely,Ultra'.split`,`[i<0?-i:i]+(i?i>0?' acidic':' alkaline':''))

console.log(f(6.40))  //  Slightly acidic
console.log(f(8.399)) //  Moderately alkaline
console.log(f(3.876)) //  Extremely acidic
console.log(f(10.60)) //  Very strongly alkaline     
console.log(f(0.012)) //  Ultra acidic
console.log(f(7.30))  //  Neutral
console.log(f(7.85))  //  Moderately alkaline
console.log(f(7.849)) //  Slightly alkaline
console.log(f(6.55))  //  Neutral

Arnauld

Posted 2017-06-19T10:14:10.323

Reputation: 111 334

1

Excel, 240 bytes

=CHOOSE((A1<6.55)+(A1<6.05)+(A1<5.55)+(A1<5.05)+(A1<4.45)+(A1<3.5)+(A1>=7.35)+(A1>=7.85)+(A1>=8.45)+(A1>9)+1,"Neutral","Slightly","Moderately","Strongly","Very Strongly","Extremely","Ultra")&IF(A1<6.55," acidic",IF(A1>=7.35," alkaline",""))

Wernisch

Posted 2017-06-19T10:14:10.323

Reputation: 2 534

0

Javascript, 222 209 bytes

x=>'Very strongly,Strongly,Moderately,Slightly,Neutral,Extremely,Ultra'.split(',',7,x-=0.049)[x>9?0:x>8.4?1:x>7.8?2:x>7.3?3:x>6.5?4:x>6?3:x>5.5?2:x>5?1:x>4.4?0:x>3.5?5:6]+(x<6.5?' acidic':x>7.3?' alkaline':'')

Still golfing it a little

var f = x=>'Very strongly,Strongly,Moderately,Slightly,Neutral,Extremely,Ultra'.split(',',7,x-=0.049)[x>9?0:x>8.4?1:x>7.8?2:x>7.3?3:x>6.5?4:x>6?3:x>5.5?2:x>5?1:x>4.4?0:x>3.5?5:6]+(x<6.5?' acidic':x>7.3?' alkaline':'')

console.log(f(6.40));
console.log(f(8.399));
console.log(f(3.876));
console.log(f(10.60));
console.log(f(0.012));
console.log(f(7.30));
console.log(f(7.85));
console.log(f(7.849));
console.log(f(6.55));

Thomas W

Posted 2017-06-19T10:14:10.323

Reputation: 746

I don't think you need to assign the function to a variable. – Zacharý – 2017-06-19T15:18:05.370