Welcome to MSDN Blogs Sign in | Join | Help

It happens a million times a day.  Somebody pays cash for something and gets change.  But there are rules, and Raymond's friend seems to like to break those rules.  Luckily for Raymond's friend, one of the rules is the customer is always right... or as Mr. Krabs would say, the money is always right.  This blog post is about a couple of the more mathematical rules.

Rule for the cashier: you must give "canonical" change.

Whether to honor requests for non-canonical change is a complicated morass I will not attempt to tackle in this blog post as too much depends on context.  But the initial offering must be canonical.

By "canonical change", I mean the cashier must give change using the smallest possible number of canonical coins and bills.  For example, (one quarter + one nickel) is a rendering of $0.30 using only two coins, while (three dimes) is three coins, so a cashier must never give change that includes three dimes.

By "canonical coins and bills" I mean (in the U.S.) this precise list:

  • penny
  • nickel
  • dime
  • quarter
  • $1 bill
  • $5 bill
  • $10 bill
  • $20 bill
I discuss usage of non-canonical (unusual) coins and bills later.

Rule 1 for the customer: "Tap, tap, no takebacks"

The tender and canonical change cannot intersect.

Don't give the cashier anything they would just hand back to you directly.

This is the rule that Raymond's friend broke - it just wastes everyone's time to play musical chairs with the money.
Actually, this rule is just a corollary of the more general rule:

Rule 2 for the customer: "No side transactions."

No subset of the tender can have the same value as any subset of canonical change for that tender.

Don't give the cashier anything that they would just hand back to you in coalesced form.

If you want to consolidate your change, go to a bank or use one of those big machines.

Corollary 1: it is always OK to pay with a single large bill.
Corollary 2: it is always OK to give exact change.

Unusual denominations:

The two-dollar bill, the dollar coin (in any of its forms), the half-dollar coin, and bills higher than $20 are "unusual" denominations that complicate the situation slightly.

Rule for the cashier: Unusual denominations stay in the drawer.

Accept them (unless there are security rules at your place of business) but they are explicitly not part of any canonical change.

Rule for the customer: Go right ahead.

You can pay with an unusual denomination provided that you do not break the "no side transactions" rule or any large-denomination security rule at the business in question.

Examples:

In the following examples, "total" is the amount owed; "tender" is the amount the customer gives to the cashier; and "change" is what the cashier gives back to the customer.

Total Tender Change Notes
$5.20 $5 bill + $2 bill $1 bill + three quarters + one nickel OK - cashier correctly accepted the $2
$5.20

$5 bill + $1 bill

two quarters + three dimes Cashier gave out more coins than necessary
$5.20 $5 bill + $1 bill half-dollar + one quarter + one nickel Cashier gave out non-canonical half-dollar
$5.20 $5 bill + four quarters three quarters + one nickel Customer gave three "takeback" quarters
$5.20 $5 bill + quarter + nickel dime OK
$5.20 $5 bill + quarter + five pennies dime OK
$5.20 $5 bill + quarter + ten pennies dime + nickel Customer got nickel for five pennies in "side transaction"

In the last row, you can think of the "side transaction" as either five pennies for a nickel or ten pennies for a dime. I prefer the former.

There's an MSDN sample of how to turn on HDCP or SCMS in a playback app.  The sample is loosely based on a test app I wrote, but there are still some rough edges.  For example, the CMFAttributeImpl<T> template is not part of the SDK or the DDK.  Also, there's a leak in the GetDigitalAudioEndpoint implementation.  (Using the private template was my bug.  The leak was someone else's.)

Exercise: find the leak.

There are also rough edges in the test app.  For one thing, it doesn't play audio - the way to use the app is to

  1. Start playing audio using your favorite audio playback application, to the digital output on which want to turn on HDCP or SCMS.
  2. Run the trustedaudiodrivers2.exe command line to do what you want it to.

Source and binaries (x86 and amd64) attached.

>trustedaudiodrivers2
trustedaudiodrivers2 --list-devices

trustedaudiodrivers2
    --device [ communications | console | multimedia | <device-name>]
    --copy-ok [ 0 | 1 ]
    --digital-output-disable [ 0 | 1 ]
    --test-certificate-enable [ 0 | 1 ]
    --drm-level <drm-level>

--list-devices: displays a list of output devices.

Sets a Trusted Audio Drivers 2 output policy on a given audio endpoint.
--device
    communications: set policy on default communications render endpoint.
    console: set policy on default console render endpoint.
    multimedia: set policy on default multimedia render endpoint.
    <device-name>: set policy on the endpoint with this long name.
--copy-ok: 1 or 0. Set to 0 to turn on "copy protection" (SCMS or HDCP)
--digital-output-disable: 1 or 0. Set to 1 to disable output (or turn on HDCP.) --test-certificate-enable: 1 or 0. Set to 1 to allow the test certificate.
--drm-level: set to a number. 1100 is a good default.

Here's a sample command line which should disable the digital out (or enable HDCP, if the driver supports it.)  This is line-wrapped for readability only.

>trustedaudiodrivers2.exe
    --device "Acer H213H (High Definition Audio Device)"
    --copy-ok 1
    --digital-output-disable 1
    --test-certificate-enable 1
    --drm-level 1300

If all goes well the output should look something like this:

Output Trust Authorities on this endpoint: 2
Processing Output Trust Authority #1 of 2
OTA action is PEACTION_PLAY (1)
GetOriginatorID() called
GetOriginatorID() called
GenerateRequiredSchemas() called
dwAttributes: MFOUTPUTATTRIBUTE_DIGITAL (0x00000001)
guidOutputSubType: MFCONNECTOR_HDMI ({57CD596D-CE47-11D9-92DB-000BDB28FF98})
cProtectionSchemasSupported: 1
MFPROTECTION_TRUSTEDAUDIODRIVERS ({65BDF3D2-0168-4816-A533-55D47B027101})
MFPROTECTION_TRUSTEDAUDIODRIVERS supported.
IMFOutputSchema::GetSchemaType called
IMFOutputSchema::GetConfigurationData called
IMFOutputTrustAuthority::SetPolicy returned 0x00000000
Processing Output Trust Authority #2 of 2
OTA action is PEACTION_EXTRACT (4)
Skipping as the OTA action is not PEACTION_PLAY
Policy successfully applied.  Press any key to release IMFTrustedOutput...

At that point I pressed a key, which redacted the policy, and the music started playing again.

Common causes of failures:

  1. No audio is playing to that device.  Setting protection requires an active audio stream.
  2. The audio device is not S/PDIF or HDMI.
  3. The audio driver is not capable of enforcing the protection.
  4. The audio driver is test-signed only; try --test-certificate-enable 1
  5. Kernel debugging is enabled.
  6. Driver verifier is enabled.

This source should compile with just publically available headers and no special voodoo on the part of the developer.

EDIT: 11/13/2009 10:05 AM

A subtle problem was called to my attention.  This line triggers an ATL ASSERT:

hr = pMFOutputTrustAuthority->SetPolicy(&pMFOutputPolicy, 1, &pbTicket, &cbTicket);

The ASSERT is in CComPtr<IMFOutputPolicy>::operator& which ASSERTs if the pointer CComPtr<IMFOutputPolicy>::p is not NULL.

My first instinct was to bypass the assertion like this:

hr = pMFOutputTrustAuthority->SetPolicy(&pMFOutputPolicy.p, 1, &pbTicket, &cbTicket);

But ASSERTs are there for a reason.  The fundamental problem here is that I'm trying to be too clever.

Despite its name, IMFOutputTrustAuthority::SetPolicy takes, not an IMFOutputPolicy *, but an array of IMFOutputPolicy *s.  A little confusing, yes.  As this is effectively a sample, I should be emphasizing this behavior, not covering it up.

So here's the fix I decided on.  Updated source and binaries attached.

// we're only setting a single policy but the API allows setting multiple policies
// (like WaitForMultipleObjects)
IMFOutputPolicy *rMFOutputPolicies[1] = { pMFOutputPolicy };
hr = pMFOutputTrustAuthority->SetPolicy(
    rMFOutputPolicies,
    ARRAYSIZE(rMFOutputPolicies),
    &pbTicket,
    &cbTicket
);

 

http://programmingpraxis.com/2009/10/09/calculating-pi/

>perl -e"print 4/(map{$n+=rand()**2+rand()**2<1}1..pop)*$n" 5000
3.1336

59 characters, plus arguments.

I was reading László Polgár's excellent book Chess: 5334 Problems, Combinations, and Games and ran across #1071, White to move and mate in 2:

The purported solution is...

1. ♘xf6+ ♚xf6
2. ♕f7#

... which, indeed, works - and there is no other mate in two that I can see - so why blog this?

Because there's a mate in one.

If you're installing Windows via a boot DVD, and you choose Custom, you have the option to rearrange partitions.  I like use this to have each drive be one big partition.

Windows 7 wants to set aside a 100 MB partition for something-or-other.  I'm sure there's a very good reason for this but I am too lazy to look up the team that owns this space and ask them what it is.

So I'm in the "Where do you want to install Windows?" stage, I've gone into "advanced drive setup", and I've deleted all the partitions.  Fine.  I then create a partition that fills the drive, and I get this popup:

Install Windows
To ensure that all Windows features work correctly, Windows might create additional partitions for system files.
OK | Cancel

After letting Windows finish installing, I jump into diskpart.exe and sure enough, Windows has created an additional partition.  A small one, to be sure... but an additional partition (horrors!)

Not being one to let Windows push me around, I decided to experiment, and came up with the following dance to allow me to just have one big partition thankyouverymuch:

  1. Boot from the Windows DVD
  2. Choose Custom (advanced) as opposed to Upgrade
  3. Go into Drive options (advanced)
  4. Delete all partitions on the drive
  5. Create a new partition - you will get the prompt above
  6. Click OK
  7. There will now be two partitions - a small (System) one and a large (Primary) one.
  8. Delete the large one.
  9. Extend the new one to fill the drive.
  10. Install Windows.
  11. Open Windows Explorer
  12. Right-click the C: drive | Properties
  13. Delete the "System Reserved" partition name
Et voilà, Windows installs perfectly happily on the single partition (confirmed with diskpart.exe post-installation.)

As preparation for moving one of my machines from Vista to Windows 7, I'm compiling a list of all the little tweaks I like to make to machines that I use a lot:

Boot from the Windows DVD.  Delete all partitions; make each hard drive one big partition.  (Hmm... apparently Windows 7 really wants a second 100 MB partition.  Do the partition dance to force it into installing on a single partition.)

In the "password hint" box, type a misleading hint.

In "Help protect your computer and improve Windows automatically", choose "Ask me later."

Once I'm in, create a new limited user (not a member of the Administrators group) and use that as my primary account.

Control Panel | Hardware and Sound | Mouse
    Pointers | Enable pointer shadow (uncheck)
    Pointer Options
        Enhance pointer precision (uncheck)
        Hide pointer while typing (uncheck)

Right-click taskbar | Properties | Taskbar
    Use small icons (check)
    Taskbar location on screen (change to "Right")
    Taskbar buttons (change to "Never combine")
    Notification area | Customize
        Turn system icons on or off
            Clock | Off (select)
            Volume | Off (select)
            Network | Off (select)
            ... turn everything off, except sometimes.
            (for example, I might leave Power on for a laptop.)
        Always show all icons and notifications on the taskbar (check)
    Use Aero Peek to preview the desktop (uncheck)

Windows Explorer | Organize
    Layout | Details pane (uncheck)
    Folder and search options | View | Advanced settings
        Always show icons, never thumbnails (check)
        Always show menus (check)
        Display file icon on thumbnails (uncheck)
        Display file size information in folder tips (uncheck)
        Display the full path in the title bar (Classic theme only) (check)
        Hidden files and folders | Show hidden files, folders, and drives (select)
        Hide empty drives in the Computer folder (uncheck)
        Hide extensions for known file types (uncheck)
        Hide protected operating system files (Recommended) (uncheck, Yes I'm sure)
        Show pop-up description for folder and desktop items (uncheck)

Control Panel | System and Security | Windows Update | Change settings
    Download updates but let me choose whether to install them (select)
    Allow all users to install updates on this computer (check)

Elevated command prompt | gpedit.msc | Local Computer Policy
    User Configuration | Administrative Templates | Windows Components
        Windows Explorer | Turn off numerical sorting in Windows Explorer (enable)
    Computer Configuration | Administrative Templates
        System
            Power Management | Video and Display Settings
                Turn Off Adaptive Display Timeout (Plugged In) (enable)
                Turn Off Adaptive Display Timeout (On Battery) (enable)
        Windows Components | Windows Update
            Do not display 'Install Updates and Shut Down' ... (enable)
            Do not adjust default option to 'Install Updates and Shut Down' ... (enable)

Control Panel | View by: Small icons (select)
    AutoPlay | Use AutoPlay for all media and devices (uncheck)
    Indexing Options | Modify | Show all locations
        Offline Files (uncheck)
        C:\Users (uncheck)
        C:\ProgramData\Microsoft\Windows\Start Menu (uncheck)
    Troubleshooting | Change settings | Computer Maintenance | Off (select)
    Windows Defender | Tools
        Automatic scanning | Automatically scan my computer (uncheck)
        Real-time protection | Use real-time protection (recommended) (uncheck)
        Administrator | Use this program (uncheck)

Right-click Start Menu | Properties
    Customize
        Computer | Don't display this item (select)
        Connect To (uncheck)
        Control Panel | Don't display this item (select)
        Default Programs (uncheck)
        Devices and Printers (uncheck)
        Documents | Don't display this item (select)
        Enable context menus and dragging and dropping (uncheck)
        Games | Don't display this item (select)
        Help (uncheck)
        Highlight newly installed programs (uncheck)
        Music | Don't display this item (select)
        Open submenus when I pause on them with the mouse pointer (uncheck)
        Personal folder | Don't display this item (select)
        Pictures | Don't display this item (select)
        Search other files and libraries | Don't search (select)
        Search programs and Control Panel (uncheck)
        Use large icons (uncheck)
        Number of recent programs to display (set to 20 to make the menu bigger)
        Number of recent items to display in Jump Lists (set to 20 to make the menu bigger)
    Store and display recently opened programs in the Start menu (uncheck)
    Store and display recently opened items in the Start menu and the taskbar (uncheck)

Right-click everything that is pinned to the taskbar
    Unpin this program from taskbar

Right-click Recycle Bin | Properties
    For each hard drive in turn (select)
        Don't move files to the Recycle Bin. Remove files immediately... (select)

Control Panel | Appearance and Personalization
    Personalization | Change desktop icons | Recycle Bin (uncheck)
    Change desktop background
        Picture Location: Solid Colors (select, choose black)

Control Panel | User Accounts | Change your account picture
    Browse for more pictures
        http://blogs.msdn.com/photos/matthew_van_eerde/images/6831850/thumb.aspx

Control Panel | Ease of access
    Change how your mouse works
        Mouse pointers | Regular Black (select)
        Prevent windows from being automatically arranged when moved to the edge of the screen (check)
    Change how your keyboard works
        Set up Sticky Keys | Turn on Sticky Keys when SHIFT is pressed five times (uncheck)
    Optimize visual display
        Turn off all unnecessary animations (when possible) (check)

Make a folder on the desktop named "_"
    Open the following folders simultaneously
        _
        C:\ProgramData\Microsoft\Windows\Start Menu
        C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu
    Copy various shortcuts from Start Menu over to _
        Notepad
        Paint
        Command Prompt
        Calculator
        ... whatever else strikes my fancy
    ... as I install programs, consider adding them here if I use them a lot

Right-click the taskbar | Toolbars | New toolbar... | Desktop | _ (Select Folder)
    Right-click the taskbar | Lock the taskbar (uncheck)
    Drag the thumb of the _ toolbar to the top of the taskbar
    Right-click _
        Show Text (uncheck)
        Show title (uncheck)
        View | Small Icons (check)
    Drag the taskbar to be a tiny bit wider so three small icons fit side-by-side
    Drag the view-active-tasks part of the taskbar to be big
    Right-click the taskbar | Lock the taskbar (check)

Make a 1-pixel-by-1-pixel black .jpg and set it as the LogonUI background

I'm sure I'm forgetting some other things.  I'll add them later when I run into them.

I could probably make a series out of this.  Possible candidates for future posts: "Tweaks I make every time I install Office", "Tweaks I make every time I install Firefox"...

Command Prompt | Alt-Space | Defaults | QuickEdit Mode (check)

Three quarters are better than a dollar because they make noise!
    -- Lilly, Lilly's Purple Plastic Purse

Last time I talked about how to calculate a sine sweep mathematically.  There's a closed-form solution which is quite elegant but, alas, useless in a practical computer implementation due to the very big numbers that are being fed to the sin(...) function.

A computer implementation will care only about the discrete samples that need to be generated.  The integral in the previous post turns out to be counterproductive - we're much more interested in the infinite sequence of φi, and more particularly in their residue mod 2π.

Here are Matlab scripts that implement a sine sweep both ways:

First, the naïve mathematical solution that just calculates the exponential:

function signal = sinesweep_nostate( ...
    start, ...
    finish, ...
    seconds, ...
    sample_rate, ...
    amplitude, ...
    initial_phase, ...
    dc ...
)
% sinesweep_nostate returns a single-channel sine logarithmic sweep
%     DO NOT USE THIS FUNCTION IN PRODUCTION
%     THIS IS A PEDAGOGICAL EXERCISE ONLY
%     THE SIGNAL THIS PRODUCES GRADUALLY DISTORTS
%     INSTEAD USE sinesweep
%    
%     start: starting frequency in Hz
%     finish: ending frequency in Hz
%     seconds: duration of sweep in seconds
%     samplerate: samples per second
%     amplitude: amplitude
%     initial_phase: starting phase
%     dc: dc

% echo these interesting intermediate values to the console
R = (finish / start) ^ (1 / seconds)
B = 2 * pi * start / log(R)
A = initial_phase - B

time = 0 : 1 / sample_rate : seconds;
phase = A + B * R .^ time;
signal = amplitude * sin(phase) + dc;

end % sinesweep_nostate

Now, the iterative version that adds up the little Δφs to calculate φi iteratively:

function signal = sinesweep( ...
    start, ...
    finish, ...
    seconds, ...
    sample_rate, ...
    amplitude, ...
    initial_phase, ...
    dc ...
)
% sinesweep returns a single-channel sine logarithmic sweep
%     start: starting frequency in Hz
%     finish: ending frequency in Hz
%     seconds: duration of sweep in seconds
%     samplerate: samples per second
%     amplitude: amplitude
%     initial_phase: starting phase
%     dc: dc

time = 0 : 1 / sample_rate : seconds;
frequency = exp( ...
    log(start) * (1 - time / seconds) + ...
    log(finish) * (time / seconds) ...
);

phase = 0 * time;
phase(1) = initial_phase;
for i = 2:length(phase)
    phase(i) = ...
        mod(phase(i - 1) + 2 * pi * frequency(i) / sample_rate, 2 * pi);
end

signal = amplitude * sin(phase) + dc;

end % sinesweep

If anything, one would expect the first to be more accurate, since it is mathematically precise, and the second is only an approximation.  But let's see how the signal produced by each of them holds up.

I calculate, and plot, the same sweep both ways, with a slight dc offset to facilitate seeing the different sweeps on the same plot.  In particular this is a logarithmic sweep from 20 kHz to 21 kHz, over 30 seconds, using 44100 samples per second, an amplitude of 0.2, an initial phase of π, and a dc of 0.25 for one and 0.26 for the other:

plot(...
    x, sinesweep(20000, 21000, 30, 44100, 0.2, pi, 0.25), 'd', ...
    x, sinesweep_nostate(20000, 21000, 30, 44100, 0.2, pi, 0.26), 's' ...
)

(x is just 1:30*44100 - necessary to allow a single plot statement.)

Note that the approximate method is plotted in diamonds, and will be 0.01 lower on the resulting graph than the "exact" method, plotted in squares.

(This takes a while to plot because there are a heckuva lot of points...)

Ah, a nice solid mass of green and blue.  I won't show it here.

OK, let's zoom in to a very early chunk of the signal - I expect these to match up closely, with only the dc offset separating the points:

Yup.  Looks pretty good - give or take a pixel (quantization error in the display.)

Now let's see what happens to the signal towards the end of the 30 seconds.

Ick.  Something's rotten in the state of Denmark.  This distortion is so bad that it's visible - you don't even have to take an FFT to see it.

Exercise: take an FFT and look at the distortion.

Advanced Exercise: demonstrate that the distortion is, in fact, in the "exact" method and not in the iterative method... that is to say, show which clock is right.

EDIT: On second glance it looks like the second picture is just showing a horizontal shift between the two signals, which is expected.  I'll need to dig deeper if I'm to prove my assertion that the iterative method produces less distortion than the "exact" method.

Bad Perl solution to the "print the open lockers" problem:

perl -e"print join', ',map{$_*$_}1..sqrt pop" 100

54 characters.  I prefer this to the 53-character solution obtained by omitting the space after the first comma.

EDIT: 49 characters:

perl -e"print map{$_*$_,' '}1..sqrt pop" 100

EDIT: 48:

perl -e"print map{$_*$_.$/}1..sqrt pop" 100

EDIT: 47:

perl -e"map{print$/.$_*$_}1..sqrt pop" 100

I still think "say" is cheating but it does afford this very short solution:

perl -E"map{say$_*$_}1..sqrt pop" 100

EDIT: Apparently I need to learn how to count. Counts above are off. Anyway, 41:

perl -e"print$_*$_,$/for 1..sqrt pop" 100

Suppose you want to generate a continuous sine-sweep from time tstart to time tend. You want the starting frequency to be ωstart, and the ending frequency to be ωend; you want the sweep to be logarithmic, so that octaves are swept out in equal times. (The alternative would be to sweep linearly, but usually logarithmic sweeping is what you want.) For today we're going to have continuous time and sample values, so sample rate and bit depth will not be part of this discussion; in particular, the units of t will be seconds, and our sample values will go from -1 to 1.

Here's a picture of want we want to end up with:

Without loss of generality, set tstart = 0. This simplifies some of the math.

Let ω(t) be the "instantaneous frequency" at time t. Advanced Exercise: Define "instantaneous frequency" mathematically.

Sweeping ω(t) logarithmically means that log ω(t) is swept linearly from log ωstart to log ωend. So

Quick check: ω(0) = ωstart, ω(tend) = ωend. Yup.

Let's define R (the rate of change of the frequency) as (ωend / ωstart)1 / tend. This formula reduces to

ω(t) = ωstart Rt

Next step is to look at phase. For a sine wave of constant frequency ω, phase progresses linearly with t on the circular interval [0, 2π):
φ = k ω t
for some constant k. If the frequency of a sine wave was 1 cycle per second, the phase would go from 0 to 2π in a single second - this reveals that the correct value of k is 2π:
φ = 2π ω t

What happens with a variable frequency? A little calculus provides the answer. Consider a small change Δt, small enough so that ω(t) is almost constant over the interval:
Δφ ≈ 2π ω(t) Δt
because over that interval the sine sweep function is well approximated by a sine wave of constant frequency ω(t).

Starting from an initial phase φstart, let Δt → 0, and:

Substitute:
u = τ log R
τ = u / log R
= du / log R

Define:
B = 2π ωstart / log R
A = φstart - B
and we have:

φ(t) = A + BRt

Just for fun, here's the explicit solution without intermediate values:

 

Now, the payoff: the signal is just the sine of the phase, so our sine sweep is:

 

or, more explicitly:

 

Ah, beautiful mathematically.

But useless practically.

Why useless?

Well, note that our equation for phase is an exponential. That expression inside the sin(...) gets very big, very quickly. Any practical implementation of sin(...) is going to be utterly useless once its argument gets beyond a certain threshold - you'll get ugly chunky steps before you're halfway into the sweep.

Nonetheless, there is a practical way to generate (pretty good) sine sweeps. More on that next time.

EDIT: all logs are base e.

Another programming contest asks to solve the Josephus problem.

Bad Perl solution (83 characters... so close...)

>perl -e"@_=(1..$ARGV[0]);++$c%$ARGV[1]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3
28

EDIT: got it down to 80.

>perl -e"@_=(1..shift);++$c%$ARGV[0]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3
28

EDIT2: 78 dropping the parentheses.

>perl -e"@_=1..shift;++$c%$ARGV[0]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3
28

EDIT3: 66, shamelessly cannibalizing others' ideas from the contest (though I refuse to use "say")

>perl -e"$k=pop;@_=1..pop;@_=grep{++$i%$k}@_ while$#_;print@_" 40 3
28

I found this programming contest interesting: here's what I've got.

perl -e "($a,$b)=@ARGV;map{$c+=$_*$b}grep{$a&$_}map{1<<$_}(0..log($a)/log 2);print$c" 7 19

I'm calling this a one-liner because the part between the quotes is less than 80 characters (75, to be exact.)  The full command line goes over :-(

Requires the inputs to be positive whole numbers.

Perfect example of Bad Perl.  Exercise: rewrite in Good Perl.

EDIT: got the whole thing down to 80 characters (with single-digit multiplicands.)

perl -e "($a,$b)=@ARGV;map{$c+=$b<<$_ if$a>>$_&1}(0..log($a)/log 2);print$c" 8 7

There's a bug that got away from me in Windows 7's HD Audio class driver (hdaudio.sys.)

Before I explain the bug, a few caveats:

If you're using Vista, there's no problem.  This only affects Windows 7.

If you use the third-party audio driver, there's no problem.  This only affects the Microsoft HD Audio class driver (hdaudio.sys.)

If your recording devices (mic and line in) are independent (can capture from both at the same time) or muxed (can capture from one or the other but not from their sum) then you're fine; this only affects mixed capture (can capture from one, from the other, or from their sum, but not from both sides of the mix independently.)

If either of your recording devices doesn't support jack presence detection then you're fine; this only affects mixed capture where both sides of the mix support jack presence detection.

Here's the bug.

  1. There are various ways to "reset" the system and bring the OS recording device state into synchronization with the hardware state
    • reboot
    • reset the HD Audio controller
    • reinstall the audio driver
    • restart the AudioEndpointBuilder service
    • unplug all recording devices in the mix
  2. The first state change (plug or unplug) after a reset works
  3. The second and further state changes are not recognized by the OS until a reset.

Here's a sample state diagram assuming a mixed Mic and Line In (click to view full-size:)

 

Workarounds:

Install the third-party audio driver instead of the HD Audio class driver.

Use audio extension cables to fool the jack presence detection hardware into thinking something is always plugged in.

Regular expressions are a tool for matching generic text.  XPath queries are a tool for matching chunks of XML.  Both are search technologies.

When using search technologies it is occasionally quite useful to have a query that will never match anything - for SQL, this would be something like "SELECT 1 WHERE 1 = 0".

My candidates for minimal unsatisfiable regular expression:

/a\bc/
\b is a zero-width assertion that matches a boundary at the beginning or end of a word - specifically, it is true between a word-ish character (\w) and a non-wordish character (\W).  Since literal "a" and "c" are both wordish characters, this will never match.

Or, if you allow Perl extensions:

/(?!)/
This is a negative lookahead for an empty string.  Since the empty string always matches everywhere, this will never match.

My candidate for minimal unsatisfiable XPath query:

/parent::*
This matches everything at or under the parent of the root element.  Since, by definition, the root element has no parent, this will never match.

In a recent post I sung the praises of square waves as a way to get a heckuva lot of power (3 dB more power than a sine wave) into a sample-range-limited signal.  It's time to take them down a notch now.

A problem with square waves is they're impossible to generate in the analog domain.  In fact, you can't even get close.

Signals generated in the analog domain are subject to physical laws regarding continuity (no teleportation) and whatnot. A common way to model these is to express (periodic) analog signals using a basis of sine waves with integral periods.  Suppose I want to generate the square wave:

f(x) = 1, -π < x < 0
-1, 0 < x < π

Graphed below are some approximations of this function using sine waves as a basis.  Note that only odd values of n are used in the sums of sin(nx).


 

The sums converge to +/-1 quite well, but there are definite "ears" at x near 0 where there's overshoot.  This doesn't appear to die down.  A closeup of one of the "ears":


 

If anything, rather than dying down, the "ears" converge to max(fn) → about 1.18, or about 9% of the "jump" from -1 to 1.  (Dym and McKean, in their 1972 book Fourier Series and Integrals, get the 9% right but incorrectly assert that the convergence is to 1.09.)

This mathematical phenomenon - Gibbs' phenomenon - is a good illustration of the difference between convergence of a series of functions and uniform convergence.

In this case, the series of partial sums pointwise converge to the square wave... for any given point x > 0 and ε > 0, the ear will eventually move to the left, and I can choose an N such that fn(x) is within of ε of 1 for all n > N...

... but the series does not uniformly converge to the square wave.  The following assertion is false: "for any given ε > 0, I can pick an N such that fn(x) is within of ε of 1 for all n > N and all x > 0."  This can be demonstrated by picking ε = 0.17, say.  For any n, even, say, n = 10100, there is an x close to 0 where f1e100(x) > 1.17.

Daylight Saving Time is a thorn in my side.

Politician: What time is it?
Scientist: What time would you like it to be?

It is my firm belief that

  1. Daylight Saving Time doesn't do any real good.
  2. Daylight Saving Time does real harm.
  3. Politicians love Daylight Saving Time because it's easy and at least it looks good.
One of the points that my congresswoman brought up is that Daylight Saving Time was originally proposed by a founding father of the US, and that therefore it must be a good idea.  (Exercise: what logical fallacy is this?)

Today I decided to actually look up the original proposal and found it quite enlightening.

Benjamin Franklin's 1784 letter to the Journal de Paris (English translation)

The full article is well worth reading, but this quote will illustrate my point:

I believe all who have common sense, as soon as they have learnt... that it is daylight when the sun rises, will contrive to rise with him; and, to compel the rest, I would propose the following regulations...

let a tax be laid... on every window that is provided with shutters...

[let] no family be permitted to be supplied with more than one pound of candles per week...

Let guards also be posted to stop all the coaches, &c. that would pass the streets after sunset...

Every morning, as soon as the sun rises, let all the bells in every church be set ringing; and if that is not sufficient?, let cannon be fired in every street, to wake the sluggards effectually, and make them open their eyes to see their true interest. 

Yes, Benjamin Franklin was the first to propose a law encouraging people to get up early.

But he was joking.

More Posts Next page »
 
Page view tracker