Full Chapter Programming Interview Problems Dynamic Programming With Solutions in Python 1St Edition Leonardo Rossi PDF

Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

Programming Interview Problems:

Dynamic Programming (with solutions


in Python) 1st Edition Leonardo Rossi
Visit to download the full and correct content document:
https://textbookfull.com/product/programming-interview-problems-dynamic-programmi
ng-with-solutions-in-python-1st-edition-leonardo-rossi/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Discovering Computer Science Interdisciplinary Problems


Principles and Python Programming 1st Edition Jessen
Havill

https://textbookfull.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-1st-
edition-jessen-havill/

Discovering Computer Science Interdisciplinary Problems


Principles and Python Programming First Edition Jessen
Havill

https://textbookfull.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-
first-edition-jessen-havill/

Discovering Computer Science: Interdisciplinary


Problems, Principles, and Python Programming 2nd
Edition Jessen Havill

https://textbookfull.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-2nd-
edition-jessen-havill/

Discovering Computer Science Interdisciplinary Problems


Principles and Python Programming 2nd Edition Jessen
Havill

https://textbookfull.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-2nd-
edition-jessen-havill-2/
Cracking C Programming Interview 500 interview
questions and explanations to sharpen your C concepts
for a lucrative programming career English Edition
Jhamb
https://textbookfull.com/product/cracking-c-programming-
interview-500-interview-questions-and-explanations-to-sharpen-
your-c-concepts-for-a-lucrative-programming-career-english-
edition-jhamb/

Robust Adaptive Dynamic Programming 1st Edition Hao Yu

https://textbookfull.com/product/robust-adaptive-dynamic-
programming-1st-edition-hao-yu/

Python Network Programming Cookbook Kathiravelu

https://textbookfull.com/product/python-network-programming-
cookbook-kathiravelu/

Python GUI Programming Cookbook Meier

https://textbookfull.com/product/python-gui-programming-cookbook-
meier/

Abstract Dynamic Programming Second Edition Dimitri P.


Bertsekas

https://textbookfull.com/product/abstract-dynamic-programming-
second-edition-dimitri-p-bertsekas/
1

Programming Interview Problems: Dynamic Programming (with solutions in Python)


Copyright 2020 Leonardo Rossi
The designations of products and technologies that appear in this book may be claimed as
trademarks by their manufacturers and sellers.
While every precaution has been taken in the preparation of this book, the publisher and
authors assume no responsibility for errors or omissions, or for damages resulting from the
use of the information contained herein.
2 Contents

Contents

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
General advice for the interview . . . . . . . . . . . . . . . . . . . . . . . 6
1 The Fibonacci sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Solution 1: brute force, 𝑂(2𝑛 ) time 7
Solution 2: dynamic programming, top-down 9
Solution 2: dynamic programming, bottom-up 11
2 Optimal stock market strategy . . . . . . . . . . . . . . . . . . . . . . . . 13
Solution 1: dynamic programming, top-down, 𝑂(𝑛) time 13
Solution 2: dynamic programming, bottom-up, 𝑂(𝑛) time 15
Variation: limited investment budget 16
Variation: limited number of transactions 17
3 Change-making . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Clarification questions 20
Solution 1: dynamic programming, top-down, 𝑂(𝑛𝑣) time 20
Solution 2: dynamic programming, bottom-up, 𝑂(𝑛𝑣) time 25
Solution 3: dynamic programming + BFS, bottom-up, 𝑂(𝑛𝑣) time 26
Variant: count the number of ways to pay (permutations) 29
Solution: dynamic-programming, top-down, 𝑂(𝑛𝑣) 29
Variant: count the number of ways to pay (combinations) 32
Solution: dynamic-programming, top-down, 𝑂(𝑛𝑣) 32
4 Number of expressions with a target result . . . . . . . . . . . . . . . . . . 36
Clarification questions 36
Solution 1: brute-force, 𝑂(2𝑛 ) time 36
Solution 2: dynamic programming, top-down, 𝑂(𝑛𝑆) time 38
Solution 3: dynamic programming + BFS, bottom-up, 𝑂(𝑛𝑆) time 39
Unit tests 41
5 Partitioning a set into equal-sum parts . . . . . . . . . . . . . . . . . . . . 43
Clarification questions 43
Solution 1: dynamic programming, top-down, 𝑂(𝑛𝑆) time 43
6 Splitting a string without spaces into words . . . . . . . . . . . . . . . . . . 46
Clarification questions 46
Solution 1: dynamic programming, top-down, 𝑂(𝑛𝑤) time 46
Solution 2: dynamic programming + BFS/DFS, bottom-up, 𝑂(𝑛𝑤) time 48
7 The number of binary search trees . . . . . . . . . . . . . . . . . . . . . . 50
Solution 1: dynamic programming, top-down, 𝑂(𝑛2 ) time 50
8 The maximum-sum subarray . . . . . . . . . . . . . . . . . . . . . . . . 55
Clarification questions 55
Solution 1: dynamic programming, 𝑂(𝑛) time, 𝑂(𝑛) space 55
Solution 2: dynamic programming, 𝑂(𝑛) time, 𝑂(1) space 61
Unit tests 61
9 The maximum-product subarray . . . . . . . . . . . . . . . . . . . . . . . 63
Clarification questions 63
Solution 1: greedy, two-pass, 𝑂(𝑛) time 63
Contents 3

Solution 2: dynamic programming, one-pass, 𝑂(𝑛) time 69


Unit tests 73
10 Shortest pair of subarrays with target sum . . . . . . . . . . . . . . . . . . 75
Clarification questions 75
Solution 1: dynamic programming + sliding window, 𝑂(𝑛) time, 𝑂(𝑛) space 75
11 Longest palindromic substring . . . . . . . . . . . . . . . . . . . . . . . . 81
Clarification questions 81
Solution 1: brute force, 𝑂(𝑛3 ) 81
Checking if a string is a palindrome 81
Checking if a string is a palindrome: a faster way 83
Putting it all together 83
Solution 2: dynamic programming, 𝑂(𝑛2 ) 84
Solution 3: dynamic programming, 𝑂(𝑛) 88
Unit tests 90
12 Longest valid parentheses substring . . . . . . . . . . . . . . . . . . . . . 92
Clarification questions 92
Solution 1: dynamic programming, bottom-up, 𝑂(𝑛) 92
Solution 3: dynamic programming, top-down, 𝑂(𝑛) 97
Unit tests 98
13 Longest increasing subsequence . . . . . . . . . . . . . . . . . . . . . . . 100
Clarification questions 100
Solution 1: dynamic programming, bottom-up, 𝑂(𝑛2 ) time, 𝑂(𝑛2 ) space 100
Solution 2: dynamic programming, bottom-up, 𝑂(𝑛2 ) time, 𝑂(𝑛) space 103
Variant: count the number of solutions 105
Solution: dynamic programming, bottom-up, 𝑂(𝑛2 ) time, 𝑂(𝑛) space 105
14 Longest arithmetic subsequence . . . . . . . . . . . . . . . . . . . . . . . 108
Clarification questions 108
Solution 1: dynamic programming, bottom-up, 𝑂(𝑛2 ) time, 𝑂(𝑛2 ) space 108
Unit tests 112
15 Dealing the best hand of cards . . . . . . . . . . . . . . . . . . . . . . . . 114
Clarification questions 114
Solution 1: brute force, 𝑂(𝑛2 ) time 114
Solution 2: dynamic programming, 𝑂(𝑛) time 115
Unit tests 116
16 Number of ways to climb stairs . . . . . . . . . . . . . . . . . . . . . . . 118
Clarification questions 118
Solution 1: dynamic programming, top-down, 𝑂(𝑛) time 118
Solution 2: dynamic programming, bottom-up, 𝑂(𝑛) time 119
Solution 3: dynamic programming, bottom-up, 𝑂(1) time 119
Unit tests 120
17 Number of paths through maze . . . . . . . . . . . . . . . . . . . . . . . 121
Clarification questions 121
Solution 1: dynamic programming, top-down, 𝑂(𝑛2 ) time 121
Solution 2: dynamic programming, bottom-up, 𝑂(𝑛2 ) time 124
Solution 3: dynamic programming, bottom-up, 𝑂(𝑛2 ) time, linear space 125
4 Contents

Unit tests 126


18 Maximum-score path through maze . . . . . . . . . . . . . . . . . . . . . 129
Clarification questions 129
Solution 1: dynamic programming, top-down, 𝑂(𝑛2 ) time 129
Solution 2: dynamic programming, bottom-up, 𝑂(𝑛2 ) time 132
Solution 3: dynamic programming, bottom-up, 𝑂(𝑛2 ) time, linear space 133
Unit tests 134
19 Subarray sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Clarification questions 137
Solution 1: brute-force, 𝑂(𝑚𝑛) 137
Solution 2: dynamic programming, 𝑂(𝑚 + 𝑛) 137
20 Submatrix sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Clarification questions 139
Solution 1: brute-force, 𝑂(𝑚𝑛2 ) 139
Solution 2: dynamic programming, 𝑂(𝑚 + 𝑛2 ) 140
Unit tests 144
21 Largest square submatrix of ones . . . . . . . . . . . . . . . . . . . . . . . 148
Clarification questions 148
Solution 1: brute-force, 𝑂(𝑛5 ) 148
Solution 2: dynamic programming, 𝑂(𝑛2 ) 150
22 Largest rectangle in skyline . . . . . . . . . . . . . . . . . . . . . . . . . 154
Clarification questions 154
Solution 1: brute-force, 𝑂(𝑛3 ) 154
Solution 2: dynamic programming, 𝑂(𝑛2 ) 155
Solution 3: dynamic programming + stack, 𝑂(𝑛) 156
23 Largest submatrix of ones . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Clarification questions 162
Solution 1: brute-force, 𝑂(𝑛6 ) 162
Solution 2: dynamic programming, 𝑂(𝑛3 ) 163
Solution 3: dynamic programming, 𝑂(𝑛2 ) 166
24 Interleaved strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Clarification questions 168
Solution 1: brute-force, 𝑂(2𝑛 ) 168
Solution 2: dynamic programming, 𝑂(𝑛2 ) 172
25 Regular expression matching . . . . . . . . . . . . . . . . . . . . . . . . 174
Clarification questions 174
Solution 1: brute-force, 𝑂(2𝑛 ) 174
Solution 2: dynamic programming, 𝑂(𝑛2 ) 178
Unit tests 180
Contents 5

Preface
Over the last decade, many companies have adopted the FANG-style interview process for
software engineer positions: programming questions that involve an algorithm design step,
and often require competitive programming solving techniques.
The advantages and disadvantages of this style of interview questions are highly debated, and
outside the scope of this book. What is important is that the questions that are asked pose
serious challenges to candidates, thus require thorough preparation.
The class of problems that are by far the most challenging is dynamic programming. This is
due to a combination of dynamic programming being rarely used in day-to-day work, and the
difficulty of finding a solution in a short amount of time, when not having prior experience
with this method.
This book presents 25 dynamic programming problems that are most commonly encoun-
tered in interviews, and several of their variants. For each problem, multiple solutions are
given, including a gradual walkthrough that shows how one may reach the answer. The goal
is not to memorize solutions, but to understand how they work and learn the fundamental
techniques, such that new, previously unseen problems can be solved with ease.
The solutions are very detailed, showing example walkthrougs, verbal explanations of the
solutions, and many diagrams and drawings. These were designed in a way that helps both
verbal and visual learners grasp the material with ease. The code implementation usually
comes last, accompanied by unit tests and complexity/performance analysis.
A particular focus has been put on code clarity and readability: during the interview, we are
expected to write code as we would on the job. This means that the code must be tidy, with
well-named variables, short functions that do one thing, modularity, comments describing
why we do certain things etc. This is, sadly, unlike most other material on dynamic pro-
gramming that one may find online, in competitive programming resources, or even in well-
known algorithm design textbooks. In fact, the poor state of the material on this topic is the
main reason I wrote this book.
I hope that you find this book useful for preparing to get the job you wish for. Whether you
like the book or not, I would appreciate your feedback through a book review.
Good luck with your interviews!
6 Contents

General advice for the interview


Find out in advance what kind of questions will be asked. Usually, they are in one or more
of the following categories: coding, algorithm design (with or without implementation),
domain-specific questions, theoretical questions, behavioral questions, live coding, debug-
ging, one-day assignments or pair programming. You should know what you need to prepare
for.
For programming questions, do not jump directly to writing code, even if the solution looks
obvious. First, ask clarification questions and go over some simple examples, to make sure
you understand the requirements well. Then, you may sketch a solution and discuss it with
the interviewer. Several iterations might be needed in case of correctness or performance
issues. Only once they agree that the solution looks fine, proceed with implementing it.
Treat the interview questions not like problems, but real job assignments. Take them seriously
and solve them thoroughly, like a professional.
Treat your interviewers as colleagues, with whom you must work together to solve the as-
signment. Shift into the mindset that you are already on the same team. Discuss and interact
with them the same way you would with colleagues on the job.
Write tidy, clean code—as much as possible given the time you have. Try to follow typi-
cal coding style guidelines for your language. For Python, you can find good guidelines at
www.python.org/dev/peps/pep-0008 and google.github.io/styleguide/pyguide.html.
Do not forget to ask about the size of the data your code needs to handle—this is important
to determine the time complexity of your solution.
If you cannot find the fastest algorithm needed to solve the problem, propose a slower one.
Sometimes you might get an idea (or a hint from the interviewer) to make it faster once you
write it. But even if you do not, any solution is better than no solution.
Try to be quick in your answer. Interviewers usually plan to ask follow-up questions. If you
do not have sufficient time left for these, your result may be poor, even if you answered the
original question well.
7

1 The Fibonacci sequence


Return the n-th number in the Fibonacci sequence. The first two numbers in the Fibonacci
sequence are equal to 1; any other number is equal to the sum of the preceding two numbers.
Example: for n = 6, the first 6 numbers of the sequence are [1, 1, 2, 3, 5, 8] so the result
is 8.

Solution 1: brute force, 𝑂(2𝑛 ) time


A straightforward solution is to implement the function recursively:
def fibonacci(n):
if n <= 2:
return 1
return fibonacci(n ­ 1) + fibonacci(n ­ 2)

The above code is correct but too slow due to redundancies. We can see this if we add logging
to the function:
import inspect
def stack_depth():
return len(inspect.getouterframes(inspect.currentframe())) ­ 1

def fibonacci(n):
print("{indent}fibonacci({n}) called".format(
indent=" " * stack_depth(), n=n))
if n <= 2:
return 1
return fibonacci(n ­ 1) + fibonacci(n ­ 2)

fibonacci(6)

We changed the code to print the argument passed to the fibonacci function. The message
is indented by the call stack depth, so that we can see better which function call is causing
which subsequent calls. Running the above code prints:
fibonacci(6) called
fibonacci(5) called
fibonacci(4) called
fibonacci(3) called
fibonacci(2) called
fibonacci(1) called
fibonacci(2) called
fibonacci(3) called
fibonacci(2) called
fibonacci(1) called
fibonacci(4) called
8 1 The Fibonacci sequence

fibonacci(3) called
fibonacci(2) called
fibonacci(1) called
fibonacci(2) called

That’s a lot of calls! If we draw the call graph, we can see that it’s an almost full binary tree:
9

Notice that the height of the binary tree is n (in this case, 6). The tree is almost full, thus
it has 𝑂(2𝑛 ) nodes. Since each node represends a call of our function, our algorithm has
exponential complexity.

Solution 2: dynamic programming, top-down


We can optimize the previous solution by avoiding redundant computations. These redun-
dancies are visible in the call graph:

• fibonacci(4) is called twice, once by fibonacci(5) and once by fibonacci(6);


• fibonacci(3) is called 3 times;
• fibonacci(2) is called 5 times;
• fibonacci(1) is called 3 times.

It does not make sense to compute, for example, the 4-th Fibonacci number twice, since it
does not change. We should compute it only once and cache the result.

Let’s use a dictionary to store the cache:


fibonacci_cache = {}
def fibonacci(n):
if n <= 2:
return 1
if n not in fibonacci_cache:
fibonacci_cache[n] = fibonacci(n ­ 1) + fibonacci(n ­ 2)
return fibonacci_cache[n]

The call graph of the optimized code looks like this:

Notice how only the first call to fibonacci(n) recurses. All subsequent calls return from
the cache the value that was previously computed.

This implementation has 𝑂(𝑛) time complexity, since exactly one function call is needed to
compute each number in the series.
10 1 The Fibonacci sequence

This strategy of caching the results of subproblems is called dynamic programming.

While the above code is correct, there are some code style issues:

• We introduced the global variable fibonacci_cache; it would be great if we could


avoid global variables, since they impact code readability;
• The code is more complicated than before due to the cache manipulations.

We can avoid adding the global variable by using instead an attribute called cache that is
attached to the function:
def fibonacci(n):
if n <= 2:
return 1
if not hasattr(fibonacci, 'cache'):
fibonacci.cache = {}
if n not in fibonacci.cache:
fibonacci.cache[n] = fibonacci(n ­ 1) + fibonacci(n ­ 2)
return fibonacci.cache[n]

The advantage is that the cache variable is now owned by the function, so no external code
is needed anymore to initialize it. The disadvantage is that the code has become even more
complicated, thus harder to read and modify.

A better approach is to keep the original function simple, and wrap it with a decorator that
performs the caching:
def cached(f):
cache = {}
def worker(*args):
if args not in cache:
cache[args] = f(*args)
return cache[args]
return worker

@cached
def fibonacci(n):
if n <= 2:
return 1
return fibonacci(n ­ 1) + fibonacci(n ­ 2)

The good news is that Python 3 has built-in support for caching decorators, so there is no
need to roll your own:
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
if n <= 2:
11

return 1
return fibonacci(n ­ 1) + fibonacci(n ­ 2)

By default lru_cache is limited to 128 entries, with least-recently used entries evicted when
the size limit is hit. Passing maxsize=None to lru_cache ensures that there is no memory
limit and all values are cached. In practice, it might be preferrable to set a limit instead of
letting memory usage increase without bounds.

Prefer standard library functionality to rolling your own


Using the standard lru_cache decorator makes the code easier to read, since it has well-
known behavior. The advange over using a custom caching method is that the reader
does not need to spend time to understand its details.

Solution 2: dynamic programming, bottom-up


While computing the Fibonacci sequence recursively is useful for pedagogical reasons, it is
more intuitive to compute it iteratively starting from the smaller numbers, just like a human
would do:
def fibonacci(n):
series = [1, 1]
while len(series) < n:
series.append(series[­1] + series[­2])
return series[­1]

The code has 𝑂(𝑛) time complexity, as well as 𝑂(𝑛) space complexity. In practice the perfor-
mance is better than the recursive implementation, since there is no overhead due to extra
function calls.

The space complexity can be reduced to 𝑂(1) if we notice that we do not need to store the
entire sequence, just the last two numbers:
def fibonacci(n):
previous = 1
current = 1
for i in range(n ­ 2):
next = current + previous
previous, current = current, next
return current

We have written an algorithm that starts from the smallest subproblem (the first two numbers
in the sequence), then expands the solution to reach the original problem (the n-th number
in the sequence). This approach is called bottom-up dynamic programming. By contrast,
the previous approach of solving the problem recursively starting from the top is called top-
down dynamic programming. Both approaches are equally valid; one or the other may be
more intuitive, depending on the problem.
12 1 The Fibonacci sequence

In the rest of the book, we will look at how we can apply dynamic programming to solving
non-trivial problems. In general, we will show both top-down and bottom-up solutions. We
will see that the top-down approach is often easier to understand and implement, however it
offers less optimization opportunities compared to bottom-up.
13

2 Optimal stock market strategy


When evaluating stock market trading strategies, it is useful to determine the maximum pos-
sible profit that can be made by trading a certain stock. Write an algorithm that, given the
daily price of a stock, computes the maximum profit that can be made by buying and selling
that stock. Assume that you are allowed to own no more than 1 share at any time, and that
you have an unlimited budget.
Example 1: The stock price over several days is [2, 5, 1]. The best strategy is to buy a share
on the first day for price 2, then sell it on the second day for price 5, obtaining a profit of 3.
Example 2: The stock price over several days is [2, 5, 1, 3]. The best strategy is to buy a
share on the first day for price 2, then sell it on the second day for price 5, obtaining a profit
of 3; then buy it again on the third day for price 1, and sell it on the fourth day for price 3,
obtaining an overall profit of 5.

Solution 1: dynamic programming, top-down, 𝑂(𝑛) time


The first idea that comes to mind while approaching this problem is using a state machine.
This is because on any day, our state can be described by:
• whether we own the share or not;
• the amount of money we have.
Between the states of consecutive days, we have only four possible transitions:
• If at the end of the previous day we did not own the share:
• buying the stock, so we now own it, but we have less money;
• avoiding the stock, so we keep our money unchanged;
• If at the end of the previous day we owned the share:
• selling the stock, so we no longer own it, and have more money;
• holding the stock, so we keep both the stock and our money unchanged.

Knowing this, we can model the entire problem using a state machine. In our initial state,
14 2 Optimal stock market strategy

we have some amount of cash and no shares. In the final state, we have some other amount
of cash (ideally higher), and no shares. In between, we have state transitions:

Solving the original problem can be reduced to finding a chain of transitions through this
state machine, that yields the maximum profit.
Notice how our state during any day only depends on the state from the previous day. This is
excellent: we can express our problem using a simple recurrence relation, just as we did for
the Fibonacci sequence problem.
The structure of the solution using a recursive algorithm looks like this:
def max_profit(daily_price):
def get_best_profit(day, have_stock):
"""
Returns the best profit that can be obtained by the end of the day.
At the end of the day:
* if have_stock is True, the trader must own the stock;
* if have_stock is False, the trader must not own the stock.
"""
# TODO ...
# Final state: end of last day, no shares owned.
last_day = len(daily_price) ­ 1
no_stock = False
return get_best_profit(last_day, no_stock)

Note that we defined a helper function get_best_profit which takes as parameters the
identifiers of a state: the day number and whether we own the stock or not at the end of the
day. We use get_best_profit to compute the profit for a specific state in the state machine.
Let’s now implement the helper using a recurrence relation. We need to consider the previous
states that can transition into the current state, and choose the best one:
@lru_cache(maxsize=None)
def get_best_profit(day, have_stock):
"""
15

Returns the best profit that can be obtained by the end of the day.
At the end of the day:
* if have_stock is True, the trader must own the stock;
* if have_stock is False, the trader must not own the stock.
"""
if day < 0:
if not have_stock:
# Initial state: no stock and no profit.
return 0
else:
# We are not allowed to have initial stock.
# Add a very large penalty to eliminate this option.
return ­float('inf')
price = daily_price[day]
if have_stock:
# We can reach this state by buying or holding.
strategy_buy = get_best_profit(day ­ 1, False) ­ price
strategy_hold = get_best_profit(day ­ 1, True)
return max(strategy_buy, strategy_hold)
else:
# We can reach this state by selling or avoiding.
strategy_sell = get_best_profit(day ­ 1, True) + price
strategy_avoid = get_best_profit(day ­ 1, False)
return max(strategy_sell, strategy_avoid)

The first part of the helper implements the termination condition, i.e. handling the initial
state, while the second part implements the recurrence. To simplify the logic of the recur-
rence we allow selling on any day including the first, but we ensure that selling on the first
day would yield a negative profit, so it’s an option that cannot be chosen as optimal.

Handle the termination condition early


It is preferrable to handle the termination condition of a recursive function in a single
place, as opposed to wrapping each call of the function with a check like if day < 0
.... Handling it early simplifies greatly the logic and makes the code easier to read.

Both the time and space complexity of this solution are 𝑂(𝑛). Note that it is important to
cache the results of the helper function, otherwise the time complexity becomes exponential
instead of linear.

Solution 2: dynamic programming, bottom-up, 𝑂(𝑛) time


Once we have implemented the top-down solution, it is easy to rewrite it as bottom-up: we
start from the initial state, and iterate day by day until we reach the final state:
16 2 Optimal stock market strategy

def max_profit(daily_price):
# Initial state: start from a reference cash amount.
# It can be any value.
# We use 0 and allow our cash to go below 0 if we need to buy a share.
cash_not_owning_share = 0
# High penalty for owning a stock initially:
# ensures this option is never chosen.
cash_owning_share = ­float('inf')
for price in daily_price:
# Transitions to the current day, owning the stock:
strategy_buy = cash_not_owning_share ­ price
strategy_hold = cash_owning_share
# Transitions to the current day, not owning the stock:
strategy_sell = cash_owning_share + price
strategy_avoid = cash_not_owning_share
# Compute the new states.
cash_owning_share = max(strategy_buy, strategy_hold)
cash_not_owning_share = max(strategy_sell, strategy_avoid)
# The profit is the final cash amount, since we start from
# a reference of 0.
return cash_not_owning_share

At each step, we only need to store the profit corresponding to the two states of that day. This
is due to the state machine not having any transitions between non-consecutive days: we
could say that at any time, the state machine does not “remember” anything from the days
before yesterday.

The time complexity is 𝑂(𝑛), but the space complexity has been reduced to 𝑂(1), since we
only need to store the result for the previous day.

Bottom-up solutions often have smaller space complexity than top-down


It is very common (with some exceptions) that bottom-up solutions have lower memory
requirements than top-down. This is due to the ability to control precisely what data we
store and what data we discard: instead of a LRU cache policy, we can keep only the data
we need. In addition, they do not suffer from the overhead of storing stack frames due
to recursion, which is a hidden cost of the top-down solutions.

Variation: limited investment budget


In a variation of the problem, the investment budget is limited: we start with a fixed amount
of money, and we are not allowed to buy a share if we cannot afford it (we cannot borrow
money).

We can adjust the solution for this constraint:


17

def max_profit(daily_price, budget):


# Initial state.
cash_not_owning_share = budget
# High penalty for owning a stock initially:
# ensures this option is never chosen.
cash_owning_share = ­float('inf')
for price in daily_price:
# Transitions to the current day, owning the stock:
strategy_buy = cash_not_owning_share ­ price
strategy_hold = cash_owning_share
# Transitions to the current day, not owning the stock:
strategy_sell = cash_owning_share + price
strategy_avoid = cash_not_owning_share
# Compute the new states.
cash_owning_share = max(strategy_buy, strategy_hold)
if cash_owning_share < 0:
# We cannot afford to buy the share at this time.
# Add a high penalty to ensure we never choose this option.
cash_owning_share = ­float('inf')
cash_not_owning_share = max(strategy_sell, strategy_avoid)
return cash_not_owning_share ­ budget

Any time the optimal cash amount in a given state goes below zero, we replace it with negative
infinity. This ensures that this path through the state machine will not be chosen. We only
have to do this for the states where we own stock. In the states where we do not own stock,
our cash amount never decreases from the previous day, so this check is not needed.

Expect follow-up questions


One of the most common mistakes candidates make is to assume that they have to solve
a single problem during a time slot of the interview. Taking too long to solve it does
not leave any time for follow-up questions, which puts the candidate at a disadvantage
compared to others. An old Italian proverb applies here: perfect is the enemy of good. Do
not get lost in too many details trying to make your solution perfect; reach an agreement
with your interviewer on when it is good enough, so that you have time to take 1-2
follow-up questions such as this one.

Variation: limited number of transactions


In anover variation of the problem, the total number of transactions that can be performed
is bounded: the stock can only be sold up to a certain number of times tx_limit.
In this variation, the state machine needs to be adjusted so that it keeps track of multiple
pieces of information:
• whether we own the stock or not at the end of the day;
18 2 Optimal stock market strategy

• how many times we have sold the stock so far.


Instead of having only 2 states each day (for owning or not owning the stock), we now have
up to 2 * tx_limit depending on how many times we have sold, per day. For each of these
states, we have to compute the best amount of money we can earn.
The transitions between the states need to take into account the operation (buying, holding,
selling, avoiding) and whether it leads to the next day state with the same transaction count
or one higher.
We can write the following implementation:
def max_profit(daily_price, tx_limit):
# cash_not_owning_share[k] = amount of cash at the end of the day,
# if we do not own the share, and we have sold k times so far.
# Initially we have sold 0 times and we start from a reference
# budget of 0. Any other state is invalid.
cash_not_owning_share = [­float('inf')] * (tx_limit + 1)
cash_not_owning_share[0] = 0
# cash_owning_share[k] = amount of cash at the end of the day,
# if we own the share, and we have sold k times so far.
# Initially we do not own any stock, so set the state to invalid.
cash_owning_share = [­float('inf')] * (tx_limit + 1)
for price in daily_price:
# Initialize the next day's states with ­Infinity,
# then update them with the best possible transition.
cash_not_owning_share_next = [­float('inf')] * (tx_limit + 1)
cash_owning_share_next = [­float('inf')] * (tx_limit + 1)
for prev_tx_count in range(tx_limit):
# Transition to the current day, owning the stock:
strategy_buy = cash_not_owning_share[prev_tx_count] ­ price
strategy_hold = cash_owning_share[prev_tx_count]
# Transitions to the current day, not owning the stock:
strategy_sell = cash_owning_share[prev_tx_count] + price
strategy_avoid = cash_not_owning_share[prev_tx_count]
# Compute the new states.
if prev_tx_count < tx_limit:
# Selling increases the tx_count by 1.
cash_not_owning_share_next[prev_tx_count + 1] = max(
cash_not_owning_share_next[prev_tx_count + 1],
strategy_sell)
# All other transitions keep tx_count the same.
cash_not_owning_share_next[prev_tx_count] = max(
cash_not_owning_share_next[prev_tx_count],
strategy_avoid)
cash_owning_share_next[prev_tx_count] = max(
cash_owning_share_next[prev_tx_count],
19

strategy_buy,
strategy_hold)
cash_not_owning_share = cash_not_owning_share_next
cash_owning_share = cash_owning_share_next
# We have multiple final states, depending on how many times we sold.
# The transaction limit may not have been reached.
# Choose the most profitable final state.
return max(cash_not_owning_share)

Master state machines


While you are reading this book, take your time to understand well how to model prob-
lems using state machines. Almost all dynamic programming problems can be solved
this way. This skill is useful not just for interviews, but also in general in your software
engineer career.
20 3 Change-making

3 Change-making

Given a money amount and a list of coin denominations, provide the combination of coins
adding up to that amount, that uses the fewest coins.

Example 1: Pay amount 9 using coin denominations [1, 2, 5]. The combination having
the fewest coins is [5, 2, 2]. A suboptimal combination is [5, 1, 1, 1, 1]: it adds up
to 9, but is using 5 coins instead of 3, thus it cannot be the solution.

Example 2: Pay amount 12 using coin denominations [1, 6, 10]. The combination having
the fewest coins is [6, 6]. A suboptimal combination is [10, 1, 1].

Clarification questions

Q: What result should be returned for total amount 0?


A: The empty list [].

Q: Is it possible that the amount cannot be paid with the given coins?
A: Yes. For example, 5 cannot be paid with coins [2, 4]. In such a situation, return None.

Solution 1: dynamic programming, top-down, 𝑂(𝑛𝑣) time

We can formulate a top-down dynamic programming solution if we model the problem as


a recurrence. For any non-zero amount that has to be paid optimally using the given coins,
we know that at least one of the coins has to be used. The problem is that we do not know
which one. If we knew, we could use that as a starting point to reach a subproblem: we could
subtract its value from the amount, then solve an instance of the problem for the remaining,
smaller amount. We would continue in this way until the remaining amount becomes 0.

However, we do not know which coin to choose first optimally. In this situation, we have
no other choice but try all possible options in brute-force style. For each coin, we subtract
its value from the amount, then solve by recurrence the subproblem—this leads to a candi-
date solution for each choice of the first coin. Once we are done, we compare the candidate
solutions and choose the one using the fewest coins.

Here is an example of how we would form the optimal change for amount 9, using coins [1,
2, 5]. We represent each amount as a node in a tree. Whenever we subtract a coin value
from that amount, we add an edge to a new node with a smaller value. Please mind that the
actual solution does not use trees, at least not explicitly: they are shown here only for clarity.
21

This diagram shows that for value 9, we have three options for choosing the first coin:

• We choose coin 1. We now have to solve the subproblem for value 9 − 1 = 8. Suppose
its optimal result is [5, 2, 1]. Then we add coin 1 to create the candidate solution
[5, 2, 1, 1] for 9.
• We choose coin 2. We now have to solve the subproblem for value 9 − 2 = 7. Suppose
the optimal result is [5, 2]. We add to it coin 2 to create the candidate solution [5,
2, 2] for 9.
• We choose coin 5. We now have to solve the subproblem for value 9 − 5 = 4. The
optimal result is [2, 2]. We add to it coin 5 to create the candidate solution [5, 2,
2] for 9.

Now that we are done solving the subproblems, we compare the candidate solutions and
choose the one using the fewest coins: [5, 2, 2].

For solving the subproblems, we use the same procedure. The only difference is that we
need to pay attention to two edge cases: the terminating condition (reaching amount 0), and
avoiding choices where we are paying too much (reaching negative amounts). To understand
these better, let’s take a look at the subproblems:
22 3 Change-making

Drawing the subproblems helps us see clearly the edge cases:


• When the amount becomes 0, we have to stop the iteration, since the subproblem is
solved and there is nothing left to be paid. We can see the 0 node in several of the
subproblem trees.
• When the amount goes below zero, the given amount cannot be formed with that
coin. For example, trying to pay amount 3 using coin 5 would require solving the
subproblem for amount -2, which does not make sense.
In addition to that, we can also notice that there are many redundancies among the sub-
problems. This is very important, as it affects the performance of the algorithm. We origi-
nally thought about solving the problem using brute force, which results in a slow algorithm:
𝑂(𝑛𝑣 ), where 𝑛 is the number of coins and 𝑣 is the value of the amount we have to pay. In other
words, the brute-force solution has exponential complexity, with very poor performance.
However, now that we know that there are redundancies among the subproblems, we can
cache their results to reduce the complexity to only 𝑂(𝑛𝑣): in each step we must try 𝑛 coins,
and we have up to 𝑣 steps (in the worst case, we pay 𝑣 with 𝑣 coins of value 1). This result is
great: we reduced the time complexity from exponential to polynomial!
We are now ready to write a first implementation of the recurrence, without caching (the
brute-force, exponential complexity solution). This is because we want to focus on the logic
of the recurrence, without distractions; we will add caching afterwards.
def make_change(coins, amount):
"""
Given a list of coin values, and an amount to be paid,
returns the shortest list of coins that add up to that amount.
If the amount to be paid is zero, the empty list is returned.
23

If the amount cannot be paid using the coins, None is returned.


"""
# Handle payment of amount zero.
if not amount:
return []
# Negative amounts cannot be paid.
if amount < 0:
return None
optimal_result = None
# Consider all the possible ways to choose the last coin.
for coin in coins:
# Solve a subproblem for the rest of the amount.
partial_result = make_change(coins, amount ­ coin)
# Skip this coin if the payment failed:
if partial_result is None:
continue
candidate = partial_result + [coin]
# Check if the candidate solution is better than the
# optimal solution known so far, and update it if needed.
if (optimal_result is None or
len(candidate) < len(optimal_result)):
optimal_result = candidate
return optimal_result

This algorithm implements the recurrence relation as explained above. Notice how we handle
the edge cases at the beginning of the function, before making any recursive calls, to avoid
infinite recursion and to keep the recursion logic as simple as possible.

Handle and eliminate edge cases early


Generally, it is preferrable to get edge cases out of the way as soon as possible, so that the
rest of the implementation is kept simple. This improves substantially the readability of
the code.

This implementation has exponential time complexity, since we have not implemented
caching yet. Let’s do that now.
Unfortunately, if we try to add caching simply adding the lru_cache decorator, we will have
a nasty surprise:
from functools import lru_cache

@lru_cache(maxsize=None)
def make_change(coins, amount):
...

This code throws the exception: TypeError: unhashable type: 'list'. This is caused by
24 3 Change-making

the inability to cache the argument coins. As a list, it is mutable, and the lru_cache deco-
rator rejects it. The decorator supports caching only arguments with immutable types, such
as numbers, strings or tuples. This is for a very good reason: to prevent bugs in case mutable
arguments are changed later (in case of lists, via append, del or changing its elements), which
would require invalidating the cache.

A joke circulating in software engineering circles says that there are only two hard problems
in computer science: cache invalidation, naming things, and off-by-one errors. To address
the former, the design of the lru_cache decorator takes the easy way out: it avoids having to
implement cache invalidation at all by only allowing immutable arguments.

Still, we need to add caching one way or another. We can work around the lru_cache limi-
tation if we notice that we do not actually need to cache the coins list—that is shared among
all subproblems. We only need to pass the remaining amount to be paid. So we write a helper
function that solves the subproblem, taking as argument only the amount. The coin list is
shared between invocations.

One way to implement this is to make the helper function nested inside the make_change
function, so that it has access to the coins argument of the outer function:
def make_change(coins, amount):
@lru_cache(maxsize=None)
def helper(amount):
...
return helper(amount)

Another way is to transform the make_change function into a method of a class, that stores
the list of coins in a class member. The helper could then be written as another method of
the class, ideally a private one. I think adding classes is overkill for what we have to do, so we
will not discuss this approach.

Here is the full solution that uses nested functions:


def make_change(coins, amount):
"""
Given a list of coin values, and an amount to be paid,
returns the shortest list of coins that add up to that amount.
If the amount to be paid is zero, the empty list is returned.
If the amount cannot be paid using the coins, None is returned.
"""
@lru_cache(maxsize=None)
def helper(amount):
# Handle payment of amount zero.
if not amount:
return []
# Negative amounts cannot be paid.
if amount < 0:
return None
25

optimal_result = None
# Consider all the possible ways to choose the last coin.
for coin in coins:
# Solve a subproblem for the rest of the amount.
partial_result = helper(amount ­ coin)
# Skip this coin if the payment failed:
if partial_result is None:
continue
candidate = partial_result + [coin]
# Check if the candidate solution is better than the
# optimal solution known so far, and update it if needed.
if (optimal_result is None or
len(candidate) < len(optimal_result)):
optimal_result = candidate
return optimal_result
return helper(amount)

How many comments should we write?


Well-written comments improve code readability, however there is a trade-off: too many
comments can be distracting, are a maintainability burden, and a sign that the code
might not be clear enough. However, for interviews, I prefer leaning towards more ver-
bosity, since we normally do not have time to refactor the code to perfection. Comments
can compensate for that.
A good rule of thumb is to use comments to explain why the code is doing something.
If you feel the need to explain what it is doing, it might be time to refactor that piece of
code into an appropriately-named function. If you do not have time to refactor during
the interview, you can add a comment like: “TODO: refactor into helper function.”

Solution 2: dynamic programming, bottom-up, 𝑂(𝑛𝑣) time


Once we have implemented the top-down solution, we can rewrite it as bottom-up: we start
from the amount 0, and keep adding coins in all possible ways until reaching the amount to
be paid:
def make_change(coins, amount):
# solutions[k] = optimal list of coins that add up to k,
# or None if no solution is known for k
solutions = [None] * (amount + 1)
# Initial state: no coins needed to pay amount 0
solutions[0] = []
# Starting from amount 0, find ways to pay higher amounts
# by adding coins.
paid = 0
while paid < amount:
26 3 Change-making

if solutions[paid] is not None:


for coin in coins:
next_paid = paid + coin
if next_paid > amount:
continue
if (solutions[next_paid] is None or
len(solutions[next_paid]) >
len(solutions[paid]) + 1):
solutions[next_paid] = solutions[paid] + [coin]
paid += 1
return solutions[amount]

This solution is iterative, which is an advantage compared to the top-down solution, since it
avoids the overheads of recursive calls. However, for certain denominations, it wastes time
by increasing the amount very slowly, in steps of 1 unit. For example, if coins = [100,
200, 500] (suppose we use bills), it does not make sense to advance in steps of 1.

In addition, a lot of space is wasted for amounts that cannot be paid. Let’s see if we can come
up with a better solution.

Solution 3: dynamic programming + BFS, bottom-up, 𝑂(𝑛𝑣) time


We can optimize the bottom-up solution by using a queue of amounts to be handled, instead
of an array. This helps in two ways: Firstly, it allows us to skip amounts that cannot be formed,
thus reducing execution time. Secondly, by not having to store amounts that cannot be paid,
memory usage is reduced.
Let’s implement it:
def simplest_change(coins, amount):
# solutions[k] = optimal list of coins that add up to amount k
# Amounts that cannot be paid are not stored.
solutions = {0: []}
# List of amounts that can be paid but have not been handled yet.
amounts_to_be_handled = collections.deque([0])
# Iterate over amounts in breadth­first order.
while amounts_to_be_handled:
paid = amounts_to_be_handled.popleft()
solution = solutions[paid]
if paid == amount:
# Due to BFS order, the first path reaching the
# required amount is the one using the smallest number
# of coins. Thus it is the optimal solution.
return solution
for coin in coins:
next_paid = paid + coin
if next_paid > amount:
27

# We can safely ignore amounts overshooting the


# target amount to be paid.
continue
if next_paid not in solutions:
solutions[next_paid] = solution + [coin]
amounts_to_be_handled.append(next_paid)
# No combination of coins could match the required amount,
# thus it cannot be paid.
return None

Notice how we are treating the (sub)problem space as a graph, which is explored in breadth-
first order (BFS). We start from the subproblem of forming the amount 0. From there, we
keep expanding using all the possible coin choices until we reach the required amount.

Let’s look at an example showing how the problem space exploration works for paying
amount 9 with coins [1, 2, 5]. We start with amount 0 and explore by adding a coin in all
possible ways. Here is the first level of the problem space graph:

The first level contains all amounts that can be paid using a single coin. After this step, we
have [1, 2, 5] in our BFS queue, which is exactly the list of nodes on the first level—hence
the name of breadth-first search.

To fill in the second level of the problem space graph, we continue the exploration a step
further for amounts 1, 2 and 5:
28 3 Change-making

The second level contains all possible amounts that can be paid with 2 coins. After this step,
we have [3, 6, 4, 7] in our BFS queue.

Notice that we discarded nodes corresponding to already known amounts, since these can
be paid with a similar or better solution (fewer coins). We have also discarded amounts that
exceed the value we have to pay (such as 10). This ensures that the graph size is bounded and
that it contains only valid/optimal nodes.

We still have not found a way to pay our target amount, 9. Let’s explore further, adding the
third level of the problem space graph:

Note that as we reached the target amount 9, we stopped drawing the rest of the level. As
it is on the third level of the tree, the amount can be paid with 3 coins. The combination is
29

2, 2 and 5, which can be found by walking the path from 0 to 9. This is the solution to the
problem.
Note that the exploration order was important: the breadth-first order guarantees that each
time we reach a new amount, the path we followed is the shortest possible in terms of num-
ber of coins used. Had we used instead another graph search algorithm, such as depth-first
search, the solution might not have been optimal.

Variant: count the number of ways to pay (permutations)


Given a money amount and a list of coin denominations, count in how many ways it is pos-
sible to pay that amount. The order matters, i.e. paying with a coin of 1 followed by a coin of
2 is considered distinct from paying with a coin of 2 followed by a coin of 1.
Example: To pay amount 3 with coins [1, 2], there are 3 possible ways: 1 + 2, 2 + 1 and
1 + 1 + 1.

Solution: dynamic-programming, top-down, 𝑂(𝑛𝑣)


Let’s analyze a slightly more complicated example: paying amount 6 with coins [1, 2, 5].
Here are all the possible ways to pay the amount:
• 6 = 5 + 1
• 6 = 1 + 5
• 6 = 2 + 2 + 2
• 6 = 2 + 2 + 1 + 1
• 6 = 2 + 1 + 2 + 1
• 6 = 2 + 1 + 1 + 2
• 6 = 1 + 2 + 2 + 1
• 6 = 1 + 2 + 1 + 2
• 6 = 1 + 1 + 2 + 2
• 6 = 2 + 1 + 1 + 1 + 1
• 6 = 1 + 2 + 1 + 1 + 1
• 6 = 1 + 1 + 2 + 1 + 1
• 6 = 1 + 1 + 1 + 2 + 1
• 6 = 1 + 1 + 1 + 1 + 2
• 6 = 1 + 1 + 1 + 1 + 1 + 1

From this list we do not see any particular rule, other than enumerating all the permutations
of the combinations of coins that add up to 6 (1 + 5, 2 + 2 + 2, 2 + 2 + 1 + 1, 2 + 1 +
1 + 1 + 1 and 1 + 1 + 1 + 1 + 1 +1). This is not very helpful.

Let’s list the payments again but sorted in lexicographic order:


• 6 = 1 + 1 + 1 + 1 + 1 + 1
• 6 = 1 + 1 + 1 + 1 + 2
• 6 = 1 + 1 + 1 + 2 + 1
• 6 = 1 + 1 + 2 + 1 + 1
• 6 = 1 + 1 + 2 + 2
Another random document with
no related content on Scribd:
Figure. 6.
Wagner’s Digestion Apparatus for Slags.

The chief objection to this method of Wagner lies in the failure to control the temperature at
which the digestion with citrate solution is made. Huston has shown, as will be described further
on, that the temperature exercises a great influence in digestion with citrate. Since the laboratory
temperature, especially in this country, may vary between 10° and 35°, it is evident that on the
same sample the Wagner method would give very discordant results at different seasons of the
year.
82. Solutions Employed in the Wagner Method.—1. Ammonium Citrate.—In one liter there
should be exactly 150 grams of citric acid and 27.93 grams of ammonia, equivalent to twenty-three
grams of nitrogen. The following example illustrates the preparation of ten liters of the solution: In
two liters of water and three and a half liters of eight per cent ammonia, 1,500 grams of citric acid
are dissolved and the cooled solution made up exactly to eight liters. Dilute twenty-five cubic
centimeters of this solution to 250 cubic centimeters and treat twenty-five cubic centimeters of this
with three grams of calcined magnesia and distill into forty cubic centimeters of half normal sulfuric
acid. Suppose the ammonia nitrogen found correspond to twenty cubic centimeters of fourth
normal soda-lye. Then in the eight liters are contained

(20.0 × 0.0035 × 8000)


————————— = 224 grams
2.5
of ammonia nitrogen. Then in order to secure in the ten liters the proper quantity of ammonia there
must be added two liters of water containing 230 - 224 = six grams of nitrogen or seven and three-
tenths grams ammonia; viz., ninety-four cubic centimeters of 0.967 specific gravity.
2. Molybdate Solution.—Dissolve 125 grams of molybdic acid in dilute two and five-tenths per
cent ammonia, avoiding a large excess of the solvent. Add 400 grams of ammonium nitrate, dilute
with water to one liter and pour the solution into one liter of nitric acid of 1.19 specific gravity. Allow
the preparation to stand for twenty-four hours at 35° and filter.
3. Magnesia Mixture.—Dissolve 110 grams of pure crystallized magnesium chlorid and 140
grams of ammonium chlorid in 700 cubic centimeters of eight per cent ammonia and 130 cubic
centimeters of water. Allow to stand several days and filter.
83. Estimation of Lime.—When the lime is to be determined in basic slags some difficulty
may be experienced by reason of danger of contamination of the oxalate precipitate with iron and
especially manganese, which is often present in slags.
Holleman[68] proposes to estimate the lime in basic slag by a modification of the methods of
Classen and Jones. The manipulation is as follows: Fifty cubic centimeters of the solution of slag,
equivalent to one gram of substance, are evaporated to a small volume, twenty cubic centimeters
of neutral ammonium oxalate solution (one to three) added to the residue and heated on a water-
bath with frequent stirring, until the precipitate is pure white and free from lumps. The time
required is usually about ten minutes. The precipitate is collected on a filter and washed with hot
water until the filtrate contains no oxalic acid. The precipitated calcium oxalate must be snow-
white. The filter is broken and the calcium oxalate washed through, first with water and finally with
warm, dilute hydrochloric acid (one to one). The calcium oxalate is dissolved by adding fifteen
cubic centimeters of concentrated hydrochloric acid, the solution evaporated to a volume of about
twenty-five cubic centimeters and ten cubic centimeters of dilute sulfuric acid (one to five), and 150
cubic centimeters of ninety-six per cent alcohol added. After standing three hours or more the
precipitate is separated by filtration and washed with ninety-six per cent alcohol until the washings
show no acid reaction with methyl orange. The calcium sulfate precipitated is dried to constant
weight. This method gives a pure precipitate of calcium sulfate, containing only traces of
manganese.
84. Estimation of Caustic Lime.—The lime mechanically present in basic slags is likely to be
found as oxid or hydroxid, especially when the sample is of recent manufacture. In the form of oxid
the lime may be determined by solution in sugar. In this process one gram of the fine slag meal is
shaken for some time with a solution of sugar, as suggested by Stone and Scheuch.[69] The
dissolved lime is separated as oxalate by treatment of the solution with the ammonium salt. The
calcium oxalate may be determined by ignition in the usual way or volumetrically by solution in
sulfuric acid and titration of the free oxalic acid with potassium permanganate solutions. The
standard solution of permanganate should be of such a strength as to have one cubic centimeter
equivalent to about 0.01 gram of iron. The iron value of the permanganate used multiplied by 0.5
will give the quantity of calcium oxid found.
85. Detection of Adulteration of Phosphatic Slags.—The high agricultural value of
phosphatic slags has led to their adulteration and even to the substitution of other bodies. Several
patents have also been granted for the manufacture of artificial slags of a value said to be an
approximation to that of the by-products of the basic pig iron process.
(1) Method of Blum.—One of the earliest methods of examining basic slag for adulterations is
the method of Blum.[70] This method rests upon the principle of the determination of the carbon
dioxid in the sample. The basic phosphatic slag is supposed to contain no carbon dioxid. This is
true only in case it is freshly prepared. The tetrabasic phosphate, after being kept for some time,
gradually absorbs carbon dioxid from the air. As high as nineteen per cent of carbon dioxid have
been found in slags which have been kept for a long while. When the slag has absorbed so much
of carbon dioxid and water from the air as to be no longer profitable for market, it can be restored
to its original condition by ignition.
(2) Method of Richter-Forster.—One of the common adulterants of tetrabasic phosphate is
aluminum phosphate. The method of detecting this when mixed with the slag is described by
Richter-Forster.[71] The method depends on the fact that soda-lye dissolves the aluminum
phosphate, although it does not dissolve any calcium phosphoric acid from the slag. Two grams of
the sample to be tested are treated with ten cubic centimeters of soda-lye of from 7° to 8° C. in a
small vessel with frequent shaking for a few hours at room temperature. After filtration the filtrate is
made acid with hydrochloric and afterwards slightly alkaline with ammonia. With pure basic slag
there is a small trace of precipitate produced, but this is due to a little silica which can be dissolved
in a slight excess of acetic acid. If, however, the basic slag contain aluminum phosphate, a dense
jelly-like precipitate of aluminum phosphate is produced.
(3) Method of Jensch.—Edmund Jensch[72] determines the tetrabasic phosphate in slags by
solution in organic acids, and prefers citric acid for this purpose. This method was also
recommended by Blum[73].
It is well known that the tetrabasic phosphate in slags is completely soluble in citric acid while
the tribasic phosphate is only slightly, if at all, attacked. The neutral ammonium salts of organic
acids do not at first attack the tribasic phosphate at all, and they do not completely dissolve the
tetrabasic phosphate. The solution used by Jensch is made as follows: Fifty grams of crystallized
citric acid are dissolved in one liter of water. A weaker acid dissolves the tetrabasic phosphate too
slowly and a stronger one attacks the tribasic phosphate present.
Schucht recommends the following method of procedure:[74] One gram of the slag, finely
ground, is treated in a beaker glass with about 150 cubic centimeters of Jensen’s citric acid
solution and warmed for twelve hours in an air-bath at from 50° to 70° with frequent shaking.
Afterwards it is diluted with 100 cubic centimeters of water, boiled for one minute and filtered. The
filter is washed thoroughly with hot water and the phosphoric acid is estimated in the filtrate in the
usual way. With artificial mixtures of basic slags and other phosphates the quantity of basic slag
can be determined by the above method.
(4) Method of Wrampelmeyer.—According to Wrampelmeyer the most convenient method for
discovering the adulteration of basic slag is the use of the microscope.[75] All finely ground natural
phosphates are light colored and with a strong magnification appear as rounded masses. In basic
slags the particles are mostly black but there are often found red-colored fragments having sharp
angles which refract their light in a peculiar way so that, with a very little experience, they can be
recognized as being distinctive marks of pure basic slag.
In artificial mixtures of these two phosphates, which we have made in our laboratory, we have
been able to detect with certainty as little as one per cent of added mineral phosphate.
One form of adulterating natural mineral phosphates has been mixing them with finely
pulverized charcoal or soot to give them the black appearance characteristic of the basic slags.
This form of adulteration is at once disclosed by simple ignition or by microscopic examination.
(5) Loss on Ignition.—If all doubts cannot be removed by the use of the microscope, the loss
on ignition should be estimated. Natural phosphates all give a high loss on ignition, ranging from
eight to twenty-four per cent, while a basic slag gives only a very slight loss on ignition, especially
when fresh. A basic slag which has stood for a long while and absorbed carbon dioxid and
moisture, may give a loss on ignition approximating, in a maximum case, the minimum loss on
ignition from a natural phosphate.
In experiments made in this laboratory in testing for loss on ignition, we have uniformly found
that natural mineral phosphates will lose from nearly one to two and one-half times as much on
ignition as a basic slag which has been kept for two years. A basic slag in the laboratory more
than two years old gave, as loss on ignition, 4.12 per cent. Several samples of finely ground
Florida phosphates gave the following percentages of loss on ignition, as compared with a sample
of slag.
Odorless phosphate 4.12.
Florida phosphates 8.06, 6.90, 9.58, 6.40, 10.38, and 10.67 respectively.
There are some mineral phosphates, however, which are ignited before being sent to the
market. We have one such sample in our laboratory from Florida which gave, on ignition, a loss of
only one and four-tenths per cent. In this case it is seen that the application of the process of
ignition would not discriminate between a basic slag and a mineral phosphate.
It may often be of interest to know what part of the loss, on ignition, is due to water in form of
moisture. In such cases the sample should first be dried to constant weight in a steam-bath and
then ignited. In the following data are found the results obtained here with samples treated as
above indicated and also ignited directly. Number one is a basic slag two years old and the others
Florida phosphates.
Heated to 100° C. then ignited. Ignited directly.
Loss at Loss on Total Loss on
100° C. ignition. loss. ignition.
No. 1 (Slag) 2.57 1.77 4.34 4.12
No. 2 (Rock) 2.61 5.19 7.80 8.06
No. 3 “ 1.09 5.77 6.86 6.90
No. 4 “ 0.42 9.20 9.62 9.58
No. 5 “ 1.81 4.83 6.64 6.40
No. 6 “ 4.36 6.52 10.88 10.83
No. 7 “ 3.31 7.01 10.32 10.67
(6) Presence of Sulfids.—Another point noticed in this laboratory is that the basic slags
uniformly contain sulfids which are decomposed upon the addition of an acid with an evolution of
hydrogen sulfid.
(7) Presence of Fluorin.—In applying the test for fluorin, it has been uniformly found here that
the mineral phosphates respond to the fluorin test while the basic slags, on the contrary, respond
to the hydrogen sulfid test. This test, however, was applied only to the few samples we have had
and may not be a uniform property.
The absence of fluorin might not prove the absence of adulteration, but its presence would, I
believe, certainly prove the fact of the adulteration in that particular sample.
The fluorin test is applied by Böttcher in the following manner:[76] From ten to fifteen grams of
the slag are placed in a beaker ten centimeters high and from five to six centimeters in diameter,
with fifteen cubic centimeters of concentrated sulfuric acid, stirred with a glass rod, and covered
with a watch-glass on the under side of which a drop of water hangs. If there be formed upon the
drop of water a white murky rim, it is proof that a mineral phosphate containing fluorin has been
added. After from five to ten minutes you can notice on the clean watch-glass the etching
produced by the hydrofluoric acid. According to Böttcher an adulteration of ten per cent of raw
phosphate in slag can be detected by this method.
(8) Solubility in Water.—Solubility in water is also a good indication, natural phosphates being
totally insoluble in water, while a considerable quantity of the basic slag will be dissolved in water
on account of the calcium oxid or hydroxid which it contains. If the loss on ignition is low, and the
volume-weight and water-solubility high, the analyst may be certain that the sample is a pure slag.
In comparative tests made in our laboratory with a sample of basic slag and seven samples of
Florida phosphate, the percentages of material dissolved by water and by a five per cent solution
of citric acid were found to be as follows:
Sol. in
five per cent
Water-soluble. citric acid.
Per cent. Per cent.

Odorless phosphate 0.97 16.10


Florida phosphate 0.01 4.15
“ “ 0.09 4.66
“ “ 0.02 3.43
“ “ 0.08 3.61
“ “ 0.02 3.79
“ “ 0.05 4.46
“ “ 0.02 4.24
From the above data it is seen that the solvent action of water especially would be of value
inasmuch as it dissolves only a mere trace of the mineral phosphates, approximating one per cent
of the amount dissolved from basic slag. In the case of the citric acid it is found that the amount of
materials soluble in this solvent for basic slag is fully four times as great as for the mineral
phosphates. Both of these processes, therefore, have considerable value for discriminating
between the pure and adulterated article of basic slag.
(9) Specific Gravity.—The estimation of the volume specific gravity is also a good indication for
judging of the purity of the slag. This is best done by weighing directly a given volume. Basic slag
will have a volume-weight of about one and nine-tenths, while natural phosphates will have about
one and six-tenths.
(10) Conclusions.—From the above résumé of the standard methods which are in use for
determining the adulteration of basic slag, it is seen that there are many cases in which grave
doubt might exist even after the careful application of all the methods mentioned. If we had only to
consider the adulteration of basic slag with certain of the mineral phosphates, that is, tricalcium
phosphate, the problem would be an easy one, but when we add to this the fact that iron and
aluminum phosphates are employed in the adulteration, and that artificial slags may be so used,
the question becomes more involved.
In doubtful cases one after another of the methods should be applied until there is no doubt
whatever of the judgment which should be rendered.

VOLUMETRIC DETERMINATION
OF PHOSPHORIC ACID.
86. Classification of Methods.—The time required for a gravimetric determination of
phosphoric acid has led analysts to try the speedier if less accurate processes, depending on the
use of volumetric methods. The chief difficulty with these methods has been in securing some
sharp method of distinguishing the end reaction. In most cases it has been found necessary to
remove a portion of the titrated solution and prepare it for final testing by subsidence or filtration.
As is well known, this method of determining the end reaction is less accurate and more time-
consuming than those processes depending on a change of color in the whole mass. All the
volumetric processes now in general use may be divided into two classes; viz., (1) the direct
precipitation of phosphoric acid and the determination of the end reaction by any appropriate
means, and (2) the previous separation of the phosphoric acid, usually by means of a citro-
magnesium or molybdenum mixture, and in the latter case the subsequent titration of the yellow
ammonium phosphomolybdate either directly or after reduction to a lower form of oxidation. In
respect of extent of application by far the most important volumetric method is the one depending
on titration by a uranium salt after previous separation by ammoniacal magnesium citrate. A
promising method after previous separation by molybdenum is the one proposed by Pemberton,
but it has not yet come into general use. For small quantities of phosphoric acid or of phosphorus,
such as are found in steels and irons, the method of Emmerton, either as originally proposed or as
modified by Dudley and Noyes, is in frequent use. Where volumetric methods are applied to
products separated by molybdic solution, the essential feature of the analytical work is to secure a
yellow precipitate of constant composition. If this could be uniformly done such methods would
rival the gravimetric processes in accuracy. Hence it is highly important in these methods that the
yellow precipitate should be secured as far as possible, under constant conditions of strength of
solution, duration of time, and manner of precipitation. In these cases, and in such only, can the
quicker volumetric methods be depended on for accurate results.
The direct volumetric precipitation of the phosphoric acid by a uranium salt or otherwise is
practiced only when the acid is combined with the alkalies and when iron and alumina are absent
and only small quantities of lime present. This method has therefore but little practical value for
agricultural purposes. In all volumetric analyses the accuracy of the burettes, pipettes, and other
graduated vessels should be proved by careful calibration. Many of the disagreements in
laboratories where the analytical work is conducted equally well can be due to no other cause than
the inaccuracy of the graduated vessels which are found in commerce. Burettes should not only
be calibrated for the whole volume but for at least every five cubic centimeters of the graduation.

URANIUM METHOD AS PRACTICED


BY THE FRENCH CHEMISTS.
87. The Uranium Method.—Since the phosphoric acid of practical use for agricultural
purposes is nearly always combined with lime, alumina, and iron, its volumetric estimation by
means of a standard solution of a uranium salt is to be preceded by a preliminary separation by
means of an ammoniacal magnesium citrate solution. The principle of the method was almost
simultaneously published by Sutton,[77] Neubauer,[78] and Pincus.[79] The phosphoric acid may
also be separated by means of molybdic solution or by tin or bismuth.[80] In practice, however, it
has been found that when the uranium method is to be used the magnesium citrate separation is
the most convenient. Since this is the method practiced almost universally in France, the method
there used will be given in detail. It is based essentially on the process described by Joulie.[81]
88. Preparation of Sample.—(1) Incineration.—Since the organic matters present in a
phosphatic fertilizer often interfere with the employment of uranium as a reagent, it is necessary to
incinerate the sample taken for analysis.[82]
(2) Solution of the Material.—All phosphates, with the exception of certain aluminum
phosphates, amblygonite for example, are easily dissolved in nitric and hydrochloric acids more or
less dilute, especially on ebullition. The best solvent, however, for calcium phosphates for the
uranium method is incontestably hydrochloric acid which also very easily dissolves the iron and
aluminum phosphates, which are often found present with calcium phosphates.
(3) Nitric Acid.—In many laboratories nitric acid is preferred in order to avoid, in part, the
solution of ferric oxid which interferes with the determination of phosphoric acid in certain
processes. Since it does not act in this way for the citro-magnesium uranium method, it is
preferable to employ hydrochloric acid, especially because it dissolves the iron completely and
permits thus the operator to judge of the success of the solvent action by the completely white
color of the residue.
(4) Pyritic Phosphates.—Certain phosphates contain pyrites which hydrochloric acid does not
dissolve, and there is left consequently, a residue more or less colored. In this case it is necessary
to add some nitric acid and to prolong the boiling until the pyrite has disappeared, since it might
retain a small quantity of phosphoric acid in the state of iron phosphate.
(5) Sulfuric Acid.—Some chemists decompose the phosphates by means of dilute sulfuric acid.
This method, which is certainly able to give good results for certain products and for certain
processes, presents numerous inconveniences which tend to render its use objectionable for
volumetric purposes. The calcium sulfate which is formed, requires prolonged washings which
lead to chances of fatal error.
If an aluminum phosphate be under examination, containing only very little or no lime, sulfuric
acid is to be preferred to hydrochloric and nitric acids, since it attacks amblygonite, which, as has
been before stated, resists the action of the other two acids. But these are cases which are met
with very rarely, and which can always be treated by the general method by previously fusing the
material with a mixture of sodium and potassium carbonate.
In the great majority of cases the decomposition by hydrochloric acid is very easily
accomplished by simply boiling in a glass vessel, and without effecting the separation of the silica.
This operation is only necessary after the substance has been fused with alkaline carbonates, or,
in case of substances which contain decomposable silicates giving gelatinous silica with
hydrochloric acid.
There are two methods [see (6) and (7)] of securing a solution of the sample taken which
varies from one to five, and even ten grams, according to the apparent homogeneity of the
material to be analyzed.
(6) Solution by Filtration and Washing.—The ordinary method can be employed consisting in
decomposing the substance by an acid, filtering, and washing the residue upon the filter, and
combining all the wash-waters to make a determinate volume. Afterwards an aliquot fraction of the
whole is taken for the precipitation. This method is long, and presents some chances of error,
when the insoluble residue is voluminous and contains silica which obstructs the pores of the
paper and renders the filtration difficult.
(7) Volumetric Solution.—It is advisable to substitute volumetric solution for solution by filtration
and washing, which is accomplished by decomposing the substances in a graduated flask, the
volume being afterwards made up to the mark with distilled water after cooling. The solution is
then filtered without washing, and by means of a pipette an aliquot part of the original volume is
taken for precipitation. Thus all retardations in the process are avoided, and likewise the chances
of error from washing on the filter. It is true that this method may lead to a certain error due to the
volume of the insoluble matter which is left undecomposed, but since this insoluble matter is
usually small in quantity, and since it is always possible to diminish the error therefrom by
increasing the volume of the solution, this cause of error is much less to be feared than those due
to the difficulties which may occur in the other method. Let us suppose, in order to illustrate the
above, that we are dealing with a phosphate containing fifty per cent of insoluble sand which may
be considered as an extreme limit. In working on four grams of the material in a flask of 100 cubic
centimeters capacity, there will be an insoluble residue of two grams occupying a volume of about
one cubic centimeter, the density of the sand being generally nearly two. The one hundred cubic
centimeter flask will then contain only ninety-nine cubic centimeters of the real solution, and the
error at the most would be 0.01. This error could be reduced to one-half by dissolving only two
grams of the material in place of four, or by making the volume up to 200 instead of 100 cubic
centimeters.
In general it may be said that the errors which do not exceed 0.01 of the total matter under
treatment, are negligible for all industrial products. The method of volumetric solution does not
present any further inconvenience. It deserves to be and has been generally adopted by reason of
its rapidity in all the laboratories where many analyses are to be made. In the volumetric method
great care should be taken not to make up to the volume until after the cooling to room
temperature, which may be speedily secured by immersing the flask in cold water. Care should
also be exercised in taking the sample for analysis by means of the pipette immediately after
filtration, and filtration should take place as soon as the volume is made up to the standard. By
operating in this way the possible variations from changes of volume due to changes of
temperature are avoided.
(8) Examination for Arsenic Acid.—When the sample examined contains pyrites, arsenic is
often present. When the decomposition has been effected by means of nitric acid, arsenic acid
may be produced. This deports itself in all circumstances like phosphoric acid, and if it is present
in the matter under examination it will be found united with the phosphoric acid and determined
therewith afterwards. It is easy to avoid this cause of error by passing first a current of sulfurous
acid through the solution, carrying it to the boiling-point in order to drive out the excess of
sulfurous acid, and afterwards precipitating the arsenic by a current of hydrogen sulfid. After
filtration, the rest of the operation can be carried on as already described.
89. Precipitation of the Phosphate by Magnesium Citrate.—By means of an accurate
pipette a quantity of the solution representing from 0.125 to 0.250 gram or more is taken,
according to the presumed richness of the product to be examined. In order that the following
operations may go on well, it is necessary that the quantity of phosphoric acid contained in the
sample should be about fifty milligrams. The sample being measured is run into a beaker, and
there are added, first, ten cubic centimeters of magnesium citrate solution, and second, a large
excess of ammonia. If the quantity of the magnesium citrate solution be sufficient, the mixture
should at first remain perfectly limpid and only become turbid at the end of some moments and
especially after the mixture is stirred.
If there should be an immediate turbidity produced it is proof that the quantity of magnesium
citrate solution employed has been insufficient, and it is necessary to begin again by doubling its
amount. Good results cannot be obtained by adding a second portion of the magnesium citrate
solution to the original, since the iron and aluminum phosphates which are once formed are
redissolved with difficulty. Many chemists at the present time abstain from using the magnesium
citrate solution and replace it by a solution of citric acid and one of magnesium sulfate, which they
pour successively into the sample under examination. This is a cause of grave errors which it is
necessary to point out. Joulie has indeed recognized the fact that the precipitation of the
phosphoric acid is not completed in presence of ammonium citrate except it is employed in
conjunction with a sufficient excess of magnesia. But the foreign matters which accompany the
phosphoric acid require different quantities of ammonium citrate in order to keep them in solution,
and it is important to increase the magnesium solution at the time of increasing the citric acid in
order to maintain them always in the same proportion. This is easily accomplished by measuring
the two solutions, but it is much more easily done by uniting them and adding them together.
90. The Magnesium Citrate Solution.—The formula originally proposed by Joulie, and
modified by Millot, and adopted by the French Association of Chemists, is as follows: Citric acid,
400 grams; pure magnesium carbonate, forty grams; caustic magnesia, twenty grams; distilled
water, half a liter. After solution, add enough of ammonia to render strongly alkaline, requiring
about 600 cubic centimeters. Make the volume up with distilled water to one and a half liters. If the
solution be turbid, it is proof that the magnesia or the carbonate employed contains some
phosphoric acid which is to be separated by filtration, and the solution can then be preserved
indefinitely.
91. Time of Subsidence.—When the phosphoric acid is precipitated by the mixture above
mentioned, it is necessary to allow it to subside for a certain time under a bell jar in order to avoid
the evaporation of the ammonia. In order to give plenty of time for this subsidence, it is well to
make the precipitations in the afternoon and the filtrations the following morning. There are thus
secured twelve to fifteen hours of repose, which is time amply sufficient for all cases.
92. Filtration and Washing.—Filtration is performed easily and rapidly upon a small filter
without folds placed in a funnel with a long stem of about two millimeters internal diameter. Placed
in a series of six or eight, they allow the filtration to take place in regular order without loss of time,
the first filter being always empty by the time the last one is filled. The supernatant liquid from the
precipitate should first be decanted on the filter, avoiding the throwing of the filtrate on the filter
which would greatly retard the process, especially if it should contain a little silica, as often
happens.
When the clear liquid is thus decanted as completely as possible, the rest of the precipitate is
treated with water to which one-tenth of its volume of ammonia has been added, and the washing
is continued by decantation as at first, and afterwards by washing upon the filter until the filtered
solution gives no precipitate with sodium phosphate. Four washings are generally sufficient to
attain this result.
If the operations which precede have been well-conducted, the total phosphoric acid contained
in the material under examination is found upon the filter-paper, except the small portion which
remains adhering to the beaker in which the precipitation has been made. The determination of
the phosphoric acid comprises the following operations: First, solution of the ammonium
magnesium phosphate and second, titration by means of a standard solution of uranium.
93. Solution of the Ammonium Magnesium Phosphate.—The phosphate which has been
collected upon the filter is dissolved by a ten per cent solution of pure nitric acid. This solution is
caused to pass into the beaker in which the precipitation was made in order to dissolve the
particles of phosphate which remain adherent to its sides; and this solution is then thrown upon
the filter. The filtrate is then received in a flask of about 150 cubic centimeters capacity, marked at
seventy-five cubic centimeters. After two or three washings with the acidulated water, the filter
itself is detached from the funnel and introduced into the vessel which contains the solution.
The whole of the filtrate being collected in the flask it is saturated by one-tenth ammoniacal
water until a slight turbidity is produced. One or two drops of dilute nitric acid are now added until
the liquor becomes limpid, and the flask is placed upon a sand-bath in order to carry the liquid to
the boiling-point. After ebullition there are added five cubic centimeters of acid sodium acetate in
order to cause the free nitric acid to disappear and immediately the titration, by means of a
standard solution of uranium, is undertaken.
94. Acid Sodium Acetate.—The acid sodium acetate is prepared as follows: Crystallized
sodium acetate, 100 grams; glacial acetic acid, fifty cubic centimeters; distilled water, enough to
make one liter.
95. Standard Solution of Uranium.—A solution of uranium is to be prepared as follows: Pure
uranium nitrate, forty grams; distilled water, about 800 cubic centimeters. Dissolve the uranium
nitrate in the distilled water and add a few drops of ammonia until a slight turbidity is produced,
and then a sufficient amount of acetic acid to cause this turbidity to disappear. The volume is then
completed to one liter with distilled water.
The uranium nitrate often contains some uranium phosphate and some ferric nitrate. It is
important that it be freed from these foreign substances. This is secured by dissolving it in distilled
water and precipitating it by sodium carbonate, which redissolves the uranium oxid and
precipitates the iron phosphate and oxid.
The filtered liquor is saturated with nitric acid, and the uranium oxid reprecipitated by ammonia.
It is then washed with distilled water by decantation and redissolved in nitric acid, as exactly as
possible, evaporated, and crystallized.
The crystals are taken up with ether, which often leaves still a little insoluble matter. The
solution is filtered, and the ether evaporated. The salt which remains is perfectly pure. It frequently
happens when the uranium nitrate has not been properly purified that the solution prepared as has
been indicated above, deposits a light precipitate of phosphate which alters its strength and
affords a cause of error. Only those solutions should be employed which have been prepared
some days in advance, and which have remained perfectly limpid.
The solution of uranium thus obtained contains uranium nitrate, a little ammonium nitrate, a
very small quantity of uranium acetate, some ammonium acetate, and a little free acetic acid. Its
sensibility is the more pronounced as the acetates present in it are less in quantity. It is important,
therefore, never to prepare the solution with uranium acetate.
96. Typical Solution of Phosphoric Acid.—In order to titrate a solution of uranium, it is
necessary to have a standard solution of phosphoric acid; that is to say, a solution containing a
precise and known quantity of that acid in a given volume. This solution is prepared by means of
acid ammonium phosphate, a salt which is easily obtained pure and dry. Sometimes as it may
contain a small quantity of neutral phosphate which modifies the relative proportions of phosphoric
acid and ammonia, and it is indispensable to have its strength verified. The titer of the typical
solution should be such that it requires for the precipitation of the phosphoric acid which it
contains, a volume of the solution of uranium almost exactly equal to its own, in order that the
expansions or contractions which the two liquors undergo, by reason of changes in the
temperature of the laboratory, should be without influence upon the results.
The solution of uranium prepared as has been indicated above, precipitates almost exactly five
milligrams of phosphoric acid per cubic centimeter; the typical solution of phosphoric acid is
prepared with eight and one-tenth grams of acid ammonium phosphate pure and dry, which is
dissolved in a sufficient quantity of distilled water to make one liter.
The acid ammonium phosphate containing 61.74 per cent of anhydrous phosphoric acid, the
quantity above gives exactly five grams of that acid in a liter, or five milligrams in a cubic
centimeter.
97. Verification of the Strength of the Standard Solution of Phosphoric Acid.—The
strength of the standard solution of phosphoric acid is verified by evaporating a known volume,
fifty cubic centimeters for example, with a solution of ferric hydroxid containing a known quantity of
ferric oxid. The mass having been evaporated to dryness, and ignited in a platinum crucible, gives
an increase in the weight of the iron oxid exactly equal to the amount of anhydrous phosphoric
acid contained therein, both the nitric acid and ammonia being driven off by the heat.
To prepare the solution of ferric hydroxid, dissolve twenty grams of iron filings in hydrochloric
acid. The solution is filtered to separate the carbon, and it is converted into ferric nitrate by nitric
acid, and the solution diluted with distilled water, and the ferric oxid precipitated by a slight excess
of ammonia. The precipitate, washed by decantation with distilled water until the wash-water no
longer gives a precipitate with silver nitrate, is redissolved in nitric acid, and the solution is
concentrated or diluted, as the case may be, to bring the volume to one liter.
In order to determine the quantity of ferric oxid which it contains, fifty cubic centimeters are
evaporated to dryness, ignited, and weighed.
A second operation like the above is carried on by adding fifty cubic centimeters of the
standard solution of phosphoric acid, and the strength of the solution thus obtained is marked
upon the flask.
If the operation have been properly carried on, three or four duplicates will give exactly the
same figures. If there are sensible differences, the whole operation should be done over from the
first.
98. Titration of the Solution of Uranium.—In a 150 cubic centimeter flask marked at seventy-
five cubic centimeters, are poured ten cubic centimeters of the standard solution of phosphoric
acid measured with an exact pipette; five cubic centimeters of the acid sodium acetate are added,
and distilled water enough to make about thirty cubic centimeters, and the whole carried to the
boiling-point. The titration is then carried on by allowing the solution of uranium to fall into the flask
from a graduated burette, thoroughly shaking after each addition of the uranium, and trying a drop
of the liquor with an equal quantity of a ten per cent solution of potassium ferrocyanid upon a
greased white plate. Since the quantity of the uranium solution present will be very nearly ten
cubic centimeters at first, nine cubic centimeters can be run in without testing. Afterwards, the
operation is continued by adding two or three drops at a time until the test upon the white plate
with the potassium ferrocyanid shows the end of the reaction. When there is observed in the final
test a slight change of tint, the flask is filled up to the mark with boiling distilled water and the
process tried anew. If in the first part of the operation the point of saturation have not been passed,
it is still usually necessary to add a drop or two of the uranium solution in order to produce the
characteristic reddish coloration, and this increase is rendered necessary by the increase in the
volume of the liquid. Proceeding in this manner two or three times allows the attainment of
extreme precision, inasmuch as the analyst knows just when to look for the point of saturation.
Correction.—The result of the preceding operation is not absolutely exact. It is evident indeed
that in addition to the quantity of uranium necessary for the exact precipitation of the phosphoric
acid, it has been necessary to add an excess sufficient to produce the reaction upon the
potassium ferrocyanid.
This excess is rendered constant by the precaution of operating always upon the same
volume; namely, seventy-five cubic centimeters. It can be determined then once for all by making
a blank determination under the same conditions but without using the phosphoric acid.
The result of this determination is that it renders possible the correction which it is necessary to
make by subtracting the quantity used in the blank titration from the preceding result in order to
obtain the exact strength of the uranium solution.
The operation is carried on as follows: In a flat-bottomed flask of about 150 cubic centimeters
capacity and marked at seventy-five cubic centimeters, by means of a pipette, are placed five
cubic centimeters of the solution of sodium acetate; some hot distilled water is added until the
flask is filled to the mark, and it is then placed upon a sand-bath and heated to the boiling-point. It
is taken from the fire, the volume made up to seventy-five cubic centimeters with a little hot
distilled water, and one or two drops of the solution of uranium are allowed to flow into the flask
from a graduated burette previously filled exactly to zero. After each drop of the solution of
uranium the flask is shaken and the liquid tried upon a drop of potassium ferrocyanid, as has been
previously indicated. For a skilled eye, four to six drops are generally necessary to obtain the
characteristic coloration; that is from two-tenths to three-tenths of a cubic centimeter. Beginners
often use from five-tenths to six-tenths, and sometimes even more.
The sole important point is to arrest the operation as soon as the reddish tint is surely seen, for
afterwards the intensity of the coloration does not increase proportionally to the quantity of liquor
employed.
It is well to note that at the end of some time the coloration becomes more intense than at the
moment when the solutions are mixed, so that care must be taken not to pass the saturation-point.
This slowness of the reaction is the more marked as there is more sodium or ammonium acetate
in the standard solutions. This is the reason that it is important to introduce always the same
quantity; namely, five cubic centimeters. This is also the reason why the uranium acetate should
not be employed in preparing the standard solution of uranium which ought to contain the least
possible amount of acetate in order that the necessary quantity which is carried into each test
should be as small as possible and remain without appreciable influence. If it were otherwise, the
sensibility of the reaction would be diminished in proportion as a larger quantity of uranium
solution was employed, giving rise to errors which would be as much more important as the
quantities of phosphoric acid to be determined were greater. The correction for the uranium
solution having been determined it is written upon the label of the bottle containing it.
Causes of Errors.—In the work which has just been described, some causes of error may
occur to which the attention of analysts should be called.
The first is the error which may arise from the consumption of the small quantity of uranium
phosphate which is taken with a stirring rod when the liquid is tested with potassium ferrocyanid. It
is very easy to be assured that the end of the reaction has really been reached. For this purpose it
is only necessary to note the quantity of the solution already employed and to add to it afterwards
four drops; shake, and make a new test with a drop of the potassium ferrocyanid placed near the
spot which the last one occupied. If a decidedly reddish tint does not appear at the moment of
removing the glass rod, it is to be concluded that the first appearance was an illusion, and the
addition of uranium is to be continued. If, on the contrary, the coloration appear of a decided tint,
the preceding number may be taken for exact. It is then always beneficial to close the titration by
this test of four supplementary drops which will exaggerate the coloration and confirm the figure
found.
The second cause of error, and one moreover which is the most frequently met with, consists
in passing the end of the reaction by adding the uranium too rapidly. In place of giving then a
coloration scarcely perceptible, the test with the drop of potassium ferrocyanid gives a very
marked coloration. In this case the analysis can still be saved. For this purpose the analyst has, at
his disposal, a tenth normal solution prepared with 100 cubic centimeters of the standard solution
of phosphoric acid diluted to one liter with distilled water. Ten cubic centimeters of this tenth
normal solution are added, and the titration continued. At the end, the amount of additional
phosphoric acid used is subtracted from the total.
A third cause of error is found in the foam which is often found in the liquid, due to the shaking.
This foam may retain a portion of the last drops of the solution of uranium which fall upon its
surface and prevent its mixture with the rest of the liquid. If the glass stirring rod in being removed
from the vessel pass through this froth charged with uranium, the characteristic coloration is
obtained before real saturation is reached. Consequently it is necessary to avoid, as much as
possible, the formation of the foam, and especially to take care never to take the drop for test after
agitation except in the middle of the liquid where the foam does not exist.
Suppose the titration has been made upon ten cubic centimeters of the normal solution of
phosphoric acid in the conditions which we have just indicated, and the figure for the uranium
obtained is 10.2 cubic centimeters; if now the correction, which may be supposed to amount to
two-tenths cubic centimeter, be subtracted there will remain ten cubic centimeters of the uranium
solution which would have precipitated exactly fifty milligrams of phosphoric acid.
The quantity of phosphoric acid which precipitates one cubic centimeter of the solution will be
consequently expressed by the proportion ⁵⁰/₁₀ = five milligrams, which is exactly the strength
required. In the example which has just been given, the inscription upon the flask holding the
standard solution would be as follows: Solution of uranium, one cubic centimeter equals five
milligrams of phosphorus pentoxid; correction, two-tenths cubic centimeter.
99. Titration of the Sample.—The strength of the solution of uranium having been exactly
determined, by means of this solution the strength of the sample in which the phosphoric acid has
been previously prepared as ammonium magnesium phosphate is ascertained. In this case the
quantity of phosphoric acid being unknown, it is necessary to proceed slowly and to duplicate the
tests in order not to pass beyond the point of saturation. From this there necessarily results a
certain error in consequence of the removal of quite a number of drops of the solution of the
sample before the saturation is complete. It is therefore necessary to make a second
determination in which there is at once added almost the quantity of the solution of uranium
determined by the first analysis. Afterwards the analysis is finished by additions of very small
quantities of uranium until saturation is reached. Suppose, for instance, that the sample was that
of a mineral phosphate, five grams of which were dissolved in 100 cubic centimeters, and of which
ten cubic centimeters of the solution prepared as above required 15.3 cubic centimeters of the
standard solution of uranium. We then would have the following data:
Mineral phosphate, five grams of the material dissolved in twenty cubic
centimeters of hydrochloric acid.
Water, sufficient quantity to make 100 cubic centimeters.
Quantity taken, ten cubic centimeters = 0.50 gram of the sample taken.
Solution of uranium required 15.3 cubic centimeters.
Correction 0.2 “ “
Actual quantity of uranium solution 15.1 “ “
Strength of the solution of uranium, one cubic centimeter =
fivemilligrams P₂O₅.

Then P₂O₅ in 0.50 gram of the material = 5 × 15.1 = 75.50 milligrams.


75.5 x 100
Then the per cent of P₂O₅ = = 15.10.
50
The sample under examination ought always to be prepared in duplicate, either by making a
single precipitation and re-solution of the ammonium magnesium phosphate which is made up to a
certain volume and an aliquot portion of which is taken for the analysis, or by making two
precipitations under the conditions previously described. When the content of phosphoric acid in
the material under examination is very nearly known, the double operation may be avoided,
especially if it be required to have rapid and only approximate analyses, such as those which are
made for general control and for the conduct of manufacturing operations. But when analyses are
to be used to serve as the basis of a law or for the control of a market, they should always be
made in duplicate, and the results ought not to be accepted when the numbers obtained are
widely different, since the agreement of the two numbers will show that the work has been well
executed.
This method of analysis, much longer to describe than to execute, gives results perfectly exact
and always concordant when it is well carried out, provided that the standard solutions, upon
which it rests for its accuracy, are correctly prepared and frequently verified in the manner
indicated.
The strength of the solution of uranium ought to be verified every three or four days. The
strength of the standard solution of phosphoric acid should be verified each time that the
temperature of the laboratory undergoes any important change. A solution prepared, for example,
in winter when the temperature of the laboratory is from 15° to 18° would no longer be exact in
summer when the temperature reaches 28° or 30°.
100. Condition of Phosphoric Acid in Superphosphates.—Superphosphates are the
products of the decomposition of phosphates by sulfuric or hydrochloric acid. They contain
phosphoric acid combined with water, with lime, with magnesia, and with iron and alumina in
various proportions.
These combinations may be classed in three categories: First, those compounds soluble in
water; second, those insoluble in water, but very soluble in ammoniacal salts of the organic acids
such as the citrate and oxalate; and third, phosphates not soluble in any of the above-named
reagents.
In the products soluble in water are met free phosphoric acid, monocalcium phosphate, acid
magnesium phosphate, and the iron and aluminum phosphates dissolved in the excess of
phosphoric acid. In the products insoluble in water but soluble in the ammonium citrate are found
bicalcium phosphate and iron and aluminum phosphates, which together constitute the
phosphates called reverted.
These compounds reduced to a very fine state of division in the process of manufacture are
considered to contain phosphoric acid of the same economic value.
101. Determination of the Total Phosphoric Acid in Superphosphates and Fertilizers.—
The process is carried on exactly as for an ordinary phosphate, and with all the care indicated in
connection with the sampling, the incineration, the solution by means of hydrochloric acid, and the
separation of the phosphoric acid in the state of ammonium magnesium phosphate, and finally in
the titration by uranium.
102. Determination of Soluble and Reverted Phosphoric Acid.—To make this
determination a method unique and applicable to all cases consists in extracting, at first, the
soluble constituents in distilled water, and following this operation by digestion in the ammonium
citrate. The products soluble in water can be determined either separately or at the same time as
the products soluble in the ammonium citrate according to the taste of the people interested,
without its being necessary to modify very greatly the method of operation.
The determination of the soluble phosphoric acid comprises first, the solution of the soluble
constituents in distilled water; second, the solution of the reverted phosphates in ammonium
citrate; third, the precipitation of the phosphoric acid dissolved in the two preceding operations,
and its determination.
103. Preparation of the Sample for Analysis.—The sample sent to the chemical expert is
prepared as has been indicated; that is to say, it is poured on a sieve of which the meshes have a
diameter of one millimeter, and sifted upon a sheet of white paper. The parts which do not pass
the sieve are broken up either by the hand or in a mortar and added, through the sieve, to the first
portions. The product is well mixed and, in this state, the mass presents all the homogeneity
desirable for analysis.
Some fertilizers are received in a pasty state which does not permit of their being sifted. It is
necessary in such a case to mix them with their own weight either of precipitated calcium sulfate
dried at 160° or with fine sand washed with hydrochloric acid and dried, which divides the particles
perfectly and permits of their being passed through the meshes of the sieve.
104. Extraction of the Products Soluble in Distilled Water.—The substance having been
prepared as has just been indicated, one and a half grams are placed in a glass mortar. Twenty
cubic centimeters of distilled water are added, and the substance gently suspended therein. After
standing for one minute, the supernatant part is decanted into a small funnel provided with a filter-
paper and placed in a flask marked at 150 cubic centimeters. This operation is repeated five times
and is terminated by an intimate breaking up of the matter with distilled water. When the volume of
100 cubic centimeters of the filtrate has been obtained, the residue in the mortar is placed on the
filter, and the washing is continued until the total volume reaches 150 cubic centimeters. The
filtrate is shaken in order to render the liquor homogeneous, and is transferred to a precipitating
glass of about 300 cubic centimeters capacity.
105. Solution of the Reverted Phosphates by Ammonium Citrate.—The filter from the
above process is detached from the funnel and is introduced into a flask marked at 150 cubic
centimeters together with sixty cubic centimeters of alkaline ammonium citrate prepared in the
following manner:

Pure citric acid, 400 grams.


Ammonia of 22°, 500 cubic centimeters.
The ammonia is poured upon the citric acid in the form of crystals in a large dish. The mass
becomes heated, and the solution takes place rapidly. When it is complete and the solution is cold
it is poured into a flask of one liter capacity, and the flask is filled up to the mark with strong
ammonia. It is preserved for use in a well-stoppered bottle. The solution must be strongly alkaline.
The flask in which the filter-paper is introduced, together with the ammonium citrate, is
stoppered and shaken violently in order to disintegrate the filter-paper and put the reverted
phosphates in suspension. There are added then about sixty cubic centimeters of distilled water,
and the flask is shaken and left for twelve hours at least, or at most for twenty-four hours. The
volume is made up to 150 cubic centimeters with distilled water, and, after mixture, the solution is
filtered.
There are thus obtained two solutions which can be precipitated together or separately
according to circumstances. The most usual process is to combine the two equal volumes of
twenty-five, fifty, or one hundred cubic centimeters, representing one-quarter, one-half, or one
gram of the material according to its presumed richness, in a precipitating flask to which are added
from ten to twenty cubic centimeters of the solution of magnesia made up as follows:
Magnesium carbonate, 50 grams.
Ammonium chlorid, 100 “
Water, 500 cubic centimeters.
Hydrochloric acid, 120 “ “
After complete solution of the solid matters in the above, add 100 cubic centimeters of
ammonia of 22° strength, and distilled water enough to make one liter.
The solutions are thoroughly mixed in a precipitating glass, an excess of ammonia added, and
allowed to stand for twelve hours under a bell jar. The phosphoric acid contained in the liquor is
separated as ammonium magnesium phosphate. It is collected upon a small filter, washed with a
little ammoniacal water, redissolved, and titrated with the uranium solution in the manner already
indicated.
Example: The following is an example of this kind of a determination:
(1) One and one-half grams of the superphosphate and distilled water
enough to make 150 cubic centimeters.
(2) Filter-paper with reverted phosphates, sixty cubic centimeters of
ammonium citrate, and a sufficient quantity of distilled water to make 150
cubic centimeters.
Aqueous solution (1) 25 cc
= 0.25 grams of the sample.
Citrate solution (2) 25 cc
Add magnesium solution twenty cubic centimeters and ammonia in
excess, and allow from twelve to twenty-four hours of digestion, then filter
and wash, dissolve and titrate.
Required of solution of uranium 8.55 cubic centimeters (1 cubic
centimeter = 5 milligrams P₂O₅).
Correction 0.20.
Remainder 8.35 × 0.005 = 0.04175 gram P₂O₅ for 0.25 gram of the
sample. Then 0.04175 ÷ 0.25 = 16.7 per cent.
From the above data there would be 16.7 per cent of phosphoric acid
soluble in water and in ammonium citrate.
If it be desirable to have separately the phosphoric acid soluble in water, a separate
precipitation is made of the aqueous solution alone by means of the magnesium citrate solution.
The precipitate washed with ammoniacal water is redissolved and titrated in the manner indicated.
In subtracting from the figures obtained with the two solutions together the number obtained for
the phosphoric acid soluble in water, the number representing the phosphoric acid soluble in
ammonium citrate alone, is obtained.
It is to be noted that the determinations with uranium require always two successive titrations.
It would therefore be an advantage in all operations to precipitate a weight of ammonium
magnesium phosphate sufficient for allowing this precipitate to be dissolved and made up to 100
cubic centimeters on which amount it would be possible to execute two, three, or four
determinations, and thus to obtain a figure absolutely incontestable.
106. Conclusions.—It has been seen from the above data that the French chemists have
worked out the uranium volumetric method with great patience and attention to detail. Where
many determinations are to be made it is undoubtedly possible for an analyst to reach a high
degree of accuracy as well as to attain a desirable rapidity, by using this method. For a few
determinations, however, the labor of preparing and setting the standard solutions required would
be far greater than the actual determinations either by the molybdate or citrate gravimetric
methods. For control work in factories and for routine work connected with fertilizer inspection, the
method has sufficient merit to justify a comparison with the processes already in use by the official
chemists of this country.
The use of an alkaline ammoniacal citrate solution, however, for the determination of reverted
acid renders any comparison of the French method with our own impossible. On the other hand
the French method for water-soluble acid is based on the same principle as our own; viz., washing
at first with successive small portions of water, and thus avoiding the decomposition of the soluble
phosphates, which is, likely to occur when too great a volume of water is added at once.
In the matter of the temperature and time as affecting the solubility of reverted acid, the French
method is also distinctly inferior to our own. The digestion is allowed to continue from twelve to
twenty-four hours, at the pleasure of the analyst, and meanwhile it is subjected to room
temperature. It is not difficult to see that this treatment in the same sample would easily yield
disagreeing results between twelve hours at a winter temperature and twenty-four hours at
summer heat.

THE DETERMINATION OF PHOSPHORIC ACID


BY TITRATION OF THE YELLOW PRECIPITATE.
107. Pemberton’s Volumetric Method.—In order to shorten the work of determining the
phosphoric acid, numerous attempts have been made to execute the final determination directly
on the yellow precipitate obtained by treating a solution of a phosphate with ammonium molybdate
in nitric acid. The composition of this precipitate appears to be somewhat variable, and this fact
has cast doubt on the methods of determination based on its weight. Its most probable
composition is expressed by the following formula, (NH₄)₃PO₄(MoO₃)₁₂. For convenience in
writing reactions this formula should usually be doubled. Pemberton has described a volumetric
determination of phosphoric acid in the yellow precipitate which has the merit of being rapid.[83]
In this laboratory the method has not given very satisfactory results when compared with the
molybdate gravimetric process. It has however attracted so much attention from analysts as to
merit description, and the details of the process are therefore given.
108. The Process.—One gram of phosphate rock, or from two to three grams of phosphatic
fertilizer, are dissolved in nitric acid, and, without evaporation, diluted to 250 cubic centimeters.
Without filtering, twenty-five cubic centimeters are placed in a four-ounce beaker and ammonia
added until a slight precipitate begins to form. Five cubic centimeters of nitric acid of one and four-
tenths specific gravity are then added, and afterwards ten cubic centimeters of saturated solution
of ammonium nitrate and enough water to make the volume about sixty-five cubic centimeters.
The contents of the beaker are boiled, and while still hot, five cubic centimeters of the aqueous
solution of ammonium molybdate added. Additional quantities of the molybdate are added, if
necessary, until the whole of the phosphorus pentoxid is thrown-out.
After allowing to settle for a moment the contents of the beaker are poured upon a filter seven
centimeters in diameter. The precipitate is thoroughly washed with water, both by decantation and
on the filter. The filter with its precipitate is transferred to a beaker and titrated with standard alkali,
in the presence of phenolphthalein. Each cubic centimeter of alkali employed should correspond to
one milligram of phosphorus pentoxid, (P₂O₅).
The reagents employed have the composition indicated below:
Ammonium Molybdate.—Ninety grams of the crystals of ammonium molybdate are placed in a
large beaker and dissolved in a little less than one liter of water. The beaker is allowed to stand
over night and the clear liquor decanted. Any undissolved acid is brought into solution in a little
ammonia water and added to the clear liquor. If a trace of phosphoric acid be present a little
magnesium sulfate is added and enough ammonia to produce a slight alkaline reaction. The
volume of the solution is then made up to one liter. Each cubic centimeter of this solution is
capable of precipitating three milligrams of phosphorus pentoxid.
Standard Potassium Hydroxid.—This solution is made of such strength that one cubic
centimeter is equivalent to one milligram of phosphorus pentoxid. Treated with acid of normal
strength, 100 cubic centimeters are required to neutralize 32.37 cubic centimeters thereof.
Standard Acid.—This should have the same strength, volume for volume, as the standard
alkali solution. It is made by diluting 323.7 cubic centimeters of normal acid to one liter.
Indicator.—The indicator to be used is an alcoholic solution of phenolphthalein, one gram in
100 cubic centimeters of sixty per cent alcohol, and half a cubic centimeter of this should be used
for each titration.
Thomson has shown[84] that of the three hydrogen atoms in phosphoric acid two must be
saturated with alkali before the reaction with phenolphthalein is neutral. Therefore, when the
yellow precipitate is broken up by an alkali, according to the reaction to follow, only four of the six
molecules of ammonium are required to form a neutral ammonium phosphate as determined by
the indicator employed. The remaining two molecules of ammonium unite with the molybdenum
forming also a salt neutral to the indicator.
Phenolphthalein is preferred because, as has been shown by Long, its results are reliable in
the presence of ammonium salts unless they be present in large quantity, and if the solution be
cold and the indicator be used in sufficient quantity.[85] To prepare the indicator for this work, one
gram of phenolphthalein is dissolved in 100 cubic centimeters of sixty percent alcohol. At least
one-half of a cubic centimeter of the solution is used for each titration.
The advantages claimed for the method are its speed and accuracy. Much time is saved by
avoiding the necessity for the removal of the silica by evaporation. The results of analyses with
and without the removal of the silica are practically identical. When the silica is not removed it is
noticed that the filtrate from the yellow precipitate has a yellow tint.
The reaction is represented by the following formula:
(NH₄)₆(PO₄)₂(MoO₃)₂₄ + 46KOH = (NH₄)₄(HPO₄)₂ + (NH₄)₂MoO₄
+ 23K₂MoO₄ + 22H₂O.
From this reaction it is seen that the total available acidity of one molecule of the yellow
precipitate titrated against phenolphthalein is equivalent to twenty-three molecules of potassium
hydroxid.
Calculation of Results.—The standard alkali is of such strength that one cubic centimeter is
equal to one per cent of phosphoric acid when one gram of material is employed and one-tenth of
it taken for each determination. In a given case one gram of a sample was taken and one-tenth of
the solution used. Fifty cubic centimeters of alkali were added to the yellow precipitate. It required
thirty-two cubic centimeters of standard alkali to neutralize the excess.
The alkali consumed by the yellow precipitate was 50 - 32 = 18. The sample therefore
contained eighteen per cent of phosphoric acid.
Comparison with Official Method.—A comparison of the Pemberton volumetric with the official
method of the Association of Agricultural Chemists has been made by Day and Bryant.[86] The
comparisons were made on samples containing from 1.45 to 37.28 per cent of phosphoric acid
and resulted as follows:
Per cent Per cent
Substance. P₂O₅, P₂O₅,
Official. Pemberton.
No. 1. Florida rock 1.45 1.32
“ 2. “ “ 4.40 4.53
“ 3. Sodium phosphate 19.78 19.99
“ 4. “ “ 19.72 19.73
“ 5. Florida rock 37.28 37.22
This near agreement shows the reliability of the method. The comparison of the Pemberton
volumetric method with the official gravimetric method was investigated by the reporter of the
Association of Official Agricultural Chemists in 1894.[87] The individual variations were found to be
greater than in the regular method but the average results were nearly identical therewith. The
method works far better with small percentages of phosphoric acid than with large. Where the
average of the results by the official methods gave 12.25 per cent, the volumetric process gave
11.90 per cent, whereas in the determination of a smaller percentage the results were 2.72 and
2.73 per cent, respectively. Kilgore proposes a variation of the method which differs from the
original in two principal points.[88] First the temperature of precipitation in the Pemberton process
is 100°; but in the modified form from 55° to 60°. At the higher temperature there is danger of
depositing molybdic acid.
The second difference is in the composition of the molybdate solution employed. The official
molybdate solution contains about sixty grams of molybdenum trioxid in a liter while the
Pemberton solution contains sixty-six grams. There is therefore not much difference in strength.
The absence of nitric acid, however, from the Pemberton solution favors the deposition of the
molybdic acid when heat is applied. Kilgore, therefore, conducts the analysis as follows: The
solution of the sample is made according to the official nitric and hydrochloric acid method for total
phosphoric acid. For the determination, twenty or forty cubic centimeters are taken, corresponding
to two-tenths or four-tenths gram of the sample. Ammonia is added until a slight precipitate is
produced and the volume is then made up, with water, to seventy-five cubic centimeters. Add
some ammonium nitrate solution, from ten to fifteen cubic centimeters, but this addition is not
necessary unless much of the nitric acid has been driven off during solution. Heat in water-bath to
60° and precipitate with some freshly filtered official molybdate solution. Allow to stand for five
minutes, filter as quickly as possible, wash four times by decantation using from fifty to seventy-
five cubic centimeters of water each time, and then wash on a filter until all acid is removed. The
solution and titration of the yellow precipitate are accomplished as in the Pemberton method. The
agreement of the results obtained by this modified method was much closer with the official
gravimetric method than those obtained by the Pemberton process.
109. Estimation of Phosphoric Acid as a Lead Compound.—In the volumetric lead method,
as described by Wavelet, the phosphoric acid is precipitated by the magnesium citrate solution as
in the uranium method of Joulie, as practiced by the French chemists, and the washing of the
precipitate and its solution in nitric acid are also conducted as in that method.[89] After solution in
nitric acid ammonia is added to neutrality and the solution is then made acid with acetic. The
phosphoric acid is precipitated in the acid solution by a standard solution of lead nitrate, the
precipitate having the formula P₂O₅3PbO.
The end reaction is determined by placing a drop of the titrated mixture on a white greased
dish in contact with a drop of a five per cent solution of potassium iodid. When all the phosphoric
acid is precipitated the least excess of the lead salt is revealed by the characteristic yellow
precipitate of lead iodid.
The author of the process claims that the lead phosphate is insoluble in the excess of acetic
acid and that the phosphate itself does not give any yellow coloration with potassium iodid. The
process is quite as exact as the uranium method and the end reaction is far sharper and the
standard reagents are easily made and preserved.[90] The method described merits, at least, a
comparative trial with the uranium process, but cannot be recommended as exact until further
approved by experience.
The reagents employed have the following composition:
(1) Disodium phosphate solution containing 10.085 grams per liter
(2) Sodium acetate “ “ 50.000 “ “ “
(3) Lead nitrate “ “ 40.000 “ “ “
(4) Potassium iodid “ “ 50.000 “ “ “
The titrations should be conducted in the cold.

110. Water-Soluble Phosphoric Acid.—Glaser has modified the volumetric method of


Kalmann and Meissels for the volumetric estimation of water-soluble phosphoric acid so as to
avoid the double titration required by the original method.[91] If methyl orange be used as an
indicator in the original method, the determination does not at once lead to the tricalcium salt, but
the liquid still contains, after neutralization, some monocalcium phosphate, which is determined by
a further titration with phenolphthalein. In the modified method the total phosphoric acid is
estimated in one operation as a tricalcium salt. This is secured, by adding, at the proper time, an
excess of calcium chlorid. Two grams of the superphosphate are shaken with water several times,
and, after settling, filtered, and the insoluble residue finally washed on the filter until the total
volume of the filtrate is a quarter of a liter. Of this, fifty cubic centimeters are taken and titrated with
tenth normal soda-lye, with addition of two drops of methyl orange, until the acid reaction has
entirely disappeared. There is then added some neutral calcium chlorid solution in excess. If iron
and alumina be present, a precipitate is produced of which no account need be made. The acid
reaction is thus restored. Five drops of the phenolphthalein solution are added and the titration
continued until the alkaline reaction is noted throughout the whole mass. Each cubic centimeter of
the soda-lye corresponds, in the first titration, to 7.1, and in the second to 3.55 milligrams of
phosphoric acid.
111. Estimation of Phosphoric Acid in the Presence of a Large Excess of Iron.—The
method given below, due to Emmerton, depends upon the precipitation of a phosphomolybdate, of
constant composition, in the presence of a large excess of iron, as in the analysis of iron and steel
and iron ores.[92] The molybdenum trioxid obtained is reduced by zinc to Mo₁₂O₁₉. The action of
permanganate on this compound is shown in the following equation:

5Mo₁₂O₁₉ + 17(K₂OMn₂O₇) = 60MoO₃ + 17K₂O + 34MnO.


Seventeen molecules of permanganate are equal to sixty molecules of molybdenum trioxid.
The iron or steel is dissolved in nitric acid, evaporated to dryness, heated, and redissolved in
hydrochloric acid, then treated again with nitric acid and evaporated until a clear and concentrated
solution is obtained free from hydrochloric acid.
The solution obtained is diluted to forty cubic centimeters with water and washed into a 400
cubic centimeter flask, making the total volume about seventy-five cubic centimeters. Add strong
ammonia, shaking after each addition, until the mass sets to a thick jelly from the ferric hydroxid.
Add a few more cubic centimeters of ammonia and shake thoroughly, being sure the ammonia is
present in excess. Add next nitric acid gradually, with shaking, until the precipitate has all
dissolved; add enough more nitric acid to make the solution a clear amber color. The volume
should now be about 250 cubic centimeters. Bring the solution to 85° and add, at once, forty cubic
centimeters of molybdate solution of the following strength: Dissolve 100 grams of molybdic acid in
300 cubic centimeters of strong ammonia and 100 cubic centimeters of water, and pour the
solution into 1,250 cubic centimeters of nitric acid (1.20); close the flask with a rubber stopper,
wrap it in a thick cloth, and shake violently for five minutes. Collect the precipitate on a filter, using
pump, and wash with dilute nitric acid (1 HNO₃ : 50 H₂O). If a thin film of the precipitate should
adhere to the flask it can be removed by the ammonia in the next operation. Wash the molybdate
precipitate into a 500 cubic centimeter flask with dilute ammonia (1 H₃N : 4 H₂O), using about
thirty cubic centimeters. Add hot dilute sulfuric acid (1 H₂SO₄ : 4 H₂O) and cover the flask with a
small funnel. Add ten grams of granulated zinc and heat until rapid action begins, and then heat
gently for five minutes. The reduction is then complete. During the reduction the colors, pink, plum,
pale green, and dark green, are seen in the molybdate solution, the latter color marking the end of
the reaction.
To remove the zinc, pour through a large folded filter, wash with cold water, and fill up the filter
once with cold water. But little oxidation takes place in this way. A port-wine color is seen on the
filter, but this does not indicate a sufficient oxidation to make an error.
In titrating, the wine color becomes fainter and finally the solution is perfectly colorless and
shows a single drop in excess of the permanganate. The permanganate solution, for convenience,
is made so that one cubic centimeter is equal to 0.0001 gram of phosphorus. With iron its value is
one cubic centimeter equals 0.006141 gram of iron; and one cubic centimeter equals 0.005574
gram of molybdenum trioxid.
112. Variation of Dudley and Noyes.—The method of Emmerton to determine small
quantities of phosphoric acid, or of phosphorus in presence of a large excess of iron, has been
modified by Dudley and Pease,[93] and by Noyes and Royse.[94] As modified, the method is not
intended for fertilizer analysis, but the principle on which it rests may some time, with proper
modifications, find application in fertilizer work. The reduction is accomplished in a Jones’ tube,[95]
much simplified, so as to render it suitable for common use. The molybdic acid is reduced to a
form, or series of forms, corresponding to molybdenum sesquioxid, as in the Emmerton method,
and subsequently as in that method, titrated by a set solution of potassium permanganate.
The iron or steel filings, containing phosphorus, are brought into solution by means of nitric
acid. For this purpose two grams of them are placed in a half liter flask together with fifty cubic

You might also like