September Coding Challenge Winner!

by Dan Murphy October 2, 2009 13:57 - commentComments (0)

We have received all of our entries and a winner has been determined.  

Sam S. from Indianapolis, IN is our winner.  Congratulations Sam!  Your gift certificate is on its way.  All participants will receive an email with the winning solution.  If anyone else would like to see it let me know.  Thanks again for everyone's participation and stay tuned for our October challenge which will be posted next week.

Thanks! 

 

Share or Bookmark this post…
  • del.icio.us
  • Furl
  • LinkedIn
  • Technorati
  • TwitThis
  • StumbleUpon
  • Sphinn
  • Reddit
  • Propeller
  • NewsVine
  • Mixx
  • Ma.gnolia
  • Google
  • Facebook
  • DZone
  • Digg
  • DotNetKicks

August Code Challenge Winner

by Dan Murphy September 1, 2009 09:12 - commentComments (0)

It's offical, another winner!

Just to recap, here is our latest challenge:

Using ASP.NET, C#, and LINQ to Objects create a web page with a form that accepts a comma delimited list of integers and outputs them into their word representation followed by a line break, with an option to sort by word, integer, or original order. Also, there needs to be an option to output 10, 20, 30, or All values.

We received a lot of good solutions but one man has seperated himself from the pack.  That guys name is Nate S. from Greenville, IN.  Nate's solution hits all the high points of the requirement and outputs a very clean reponse to the user.  Great job Nate!  Your gift certificate should be in your inbox within the hour.

We truly appreciate all of our participants for taking part and stay tuned for our September challenge!

Nate's winning solution!

<!--Start of Default.aspx-->
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Aug2009CodeChallenge._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Aug2009CodeChallenge</title>
<style type="text/css">
body { font-size: 12px; font-family:Arial; padding:0px; margin:10px; border:0px;}
p { padding:0px; margin:0px; padding-bottom:5px; }
div { padding:0px; margin:0px; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>Insert a list of comma delimited numbers anywhere between -79228162514264337593543950335 and 79228162514264337593543950335</p>
<p><asp:TextBox ID="txtInts" runat="server" Width="770" /> </p>
<p>Select the number of results to return:
<asp:DropDownList ID="ddlNumberOfOutputs" runat="server">
<asp:ListItem Selected="True" Value="All" />
<asp:ListItem Value="10" />
<asp:ListItem Value="20" />
<asp:ListItem Value="30" />
</asp:DropDownList></p>
<p>Select the order in which to return:
<asp:DropDownList ID="ddlOrderToReturn" runat="server">
<asp:ListItem Selected="True" Value="Original Order" />
<asp:ListItem Value="Word" />
<asp:ListItem Value="Integer" />
</asp:DropDownList></p>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_OnClick" Text="Submit" />
<div>
<asp:DataGrid ID="dgResults" runat="server" >
<Columns>
<asp:BoundColumn HeaderText="" />
</Columns>
</asp:DataGrid>
</div>
</div>
</form>
</body>
</html>
<!--Start of Default.aspx.cs-->
using System;
using System.Linq;
using System.Collections.Generic;
namespace Aug2009CodeChallenge
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_OnClick(object sender, System.EventArgs e)
{
//TODO: Add some input validation
string[] numArray = txtInts.Text.Split(',');
int takeNum = (ddlNumberOfOutputs.SelectedItem.ToString().Equals("All")) ? numArray.Count() : int.Parse(ddlNumberOfOutputs.SelectedItem.ToString());
List<Number> numList = (from num in numArray select new Number(num)).Take(takeNum).ToList();
dgResults.DataSource = from num in numList orderby this.GetOrderBy(ddlOrderToReturn.SelectedValue, num) select num.word;
dgResults.DataBind();
}
private object GetOrderBy(string orderToReturn, Number num)
{
if(orderToReturn.Equals("Word"))
return num.word;
if(orderToReturn.Equals("Integer"))
return num.digit;
return null;
}
}
}
<!--Start of Number.cs-->
using System;
namespace Aug2009CodeChallenge
{
public partial class Number
{
public decimal digit { get; set; }
public string word { get; set; }
public Number(string d)
{
digit = decimal.Parse(d);
word = this.wordify((Decimal)digit);
}
private string wordify(decimal v)
{
if (v == 0) return "zero";
var units = "|one|two|three|four|five|six|seven|eight|nine".Split('|');
var teens = "|eleven|twelve|thir#|four#|fif#|six#|seven#|eigh#|nine#".Replace("#", "teen").Split('|');
var tens = "|ten|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety".Split('|');
var thou = "|thousand|m#|b#|tr#|quadr#|quint#|sex#|sept#|oct#".Replace("#", "illion").Split('|');
var g = (v < 0) ? "minus " : "";
var w = "";
var p = 0;
v = Math.Abs(v);
while (v > 0)
{
int b = (int)(v % 1000);
if (b > 0)
{
var h = (b / 100);
var t = (b - h * 100) / 10;
var u = (b - h * 100 - t * 10);
var s = ((h > 0) ? units[h] + " hundred" + ((t > 0 | u > 0) ? " and " : "") : "")
+ ((t > 0) ? (t == 1 && u > 0) ? teens[u] : tens[t] + ((u > 0) ? "-" : "") : "")
+ ((t != 1) ? units[u] : "");
s = (((v > 1000) && (h == 0) && (p == 0)) ? " and " : (v > 1000) ? ", " : "") + s;
w = s + " " + thou[p] + w;
}
v = v / 1000;
p++;
}
return g + w;
}
}
}
Share or Bookmark this post…
  • del.icio.us
  • Furl
  • LinkedIn
  • Technorati
  • TwitThis
  • StumbleUpon
  • Sphinn
  • Reddit
  • Propeller
  • NewsVine
  • Mixx
  • Ma.gnolia
  • Google
  • Facebook
  • DZone
  • Digg
  • DotNetKicks

July SQL Code Challenge - Winner

by Dan Murphy August 3, 2009 14:18 - commentComments (0)

Drumroll please!  The winner of the July SQL Code Challenge is...Greg B.!  Greg's solution might not be the most elegant way to handle the remainder but it is effective.  His code is below. 

CREATE PROCEDURE prCreatePaymentSchedule(@TotalSaleAmount Decimal(12,2), @TaxRate Decimal(12,2), @NumPaymentsToSpan int)
AS
BEGIN
SET NOCOUNT ON
Declare @Start int --Used for while loop
Declare @SumValue Decimal(12,2)
Create Table #TempPayment (ID int Identity(1,1), PreTaxPayment decimal(12,2), TaxAmount decimal(12,2), TotalPayment Decimal(12,2))
Set @Start = 1
While @Start <= @NumPaymentsToSpan
BEGIN
--In cases when the amount is small and num payments is WAAAYYY out there this will 
--prevent negatives from happening, but the last payment may be bigger than the others
IF (Select SUM(totalPayment) + (@TotalSaleAmount / @NumPaymentsToSpan) From #TempPayment) > @TotalSaleAmount 
BEGIN
Insert into #TempPayment (TotalPayment)
Select @TotalSaleAmount - Sum(totalPayment) FROM #TempPayment
Set @Start = @NumPaymentsToSpan  --Set @Start to the num of payments so it doesn't look again
END
ELSE If @Start = @NumPaymentsToSpan --If we are on the last payment then take do the math on what is in the table to get the last payment.
BEGIN
Insert into #TempPayment (TotalPayment)
Select @TotalSaleAmount - Sum(totalPayment) FROM #TempPayment
END
ELSE
BEGIN
--Case to do the "even" thing
--If whole number leave it alone
--If even leave it alone
--If odd then add .01 to make it even.
Insert into #TempPayment (TotalPayment)
Select Case
When ceiling((@TotalSaleAmount / @NumPaymentsToSpan)) = (@TotalSaleAmount /@NumPaymentsToSpan) Then (@TotalSaleAmount/@NumPaymentsToSpan) --Whole Number, leave alone
When (Cast((@TotalSaleAmount / @NumPaymentsToSpan) % 2 as int)) = 0 Then (@TotalSaleAmount/@NumPaymentsToSpan) --Even leave calc alone
When (Cast((@TotalSaleAmount / @NumPaymentsToSpan) % 2 as int)) = 1 Then (@TotalSaleAmount/@NumPaymentsToSpan) + .01 --Odd add .01
END
END
Set @Start = @Start + 1 --Increase Start
END
--Update #TempPayment for TaxAmount Based on Total Payment and Passed in TaxRate
--Update #TempPayment for PreTaxpayment Based on TaxAmount and total Payment.
Update #TempPayment
Set TaxAmount = (TotalPayment - (TotalPayment / (1+@TaxRate))),
PreTaxPayment = TotalPayment - (TotalPayment - (TotalPayment / (1+@TaxRate)))
--Return the recordset
Select ID, PreTaxPayment, TaxAmount, TotalPayment From #TempPayment Order by ID ASC
SET NOCOUNT OFF
END

I do have to mention that Chad H. had the most elegant solution by using the ROW_NUMBER and OVER clause.  His code is below. 

-- Assumes the following table exists 
CREATE TABLE dbo.tmp_Payments
(	ID					INT  
,PreTaxPayment		DECIMAL(32,2)			
,TaxAmount			DECIMAL(32,5)
,TotalPayment		DECIMAL(32,2)
)
GO 
if OBJECTPROPERTY(object_id('dbo.usp_Payments_INS'), 'IsProcedure') = 1
Drop Procedure usp_Payments_INS
GO 
/*
dbo.usp_GenPayments
Calcualtes payment and tax information for a total value. 
Explanation of Approach
As a DBA, I generally create a physical "integer Dim table" that contains numbers 1 - 73048
(AKA 01/01/1900 - 12/31/2099) that I use for just an occasion, but since this not mentioned
in the challenge I will generate it in the stored procedure (NOT a best practice) 
CREATE TABLE Int_Dim
(	Val		INT )
Val
---
1
2
3
4
.
.
. 
Modifications
07/01/2009 Chad H. - Created
*/
CREATE PROCEDURE dbo.usp_Payments_INS
(	@Total		DECIMAL(32,2)		-- Total amount charged
,@Tax		Decimal(3,3)		-- Tax amount (assumes decimal version) 
,@Payments	INT					-- Number of Payments
)
AS 
BEGIN 
SET NOCOUNT ON
-- Start of Integer Dimision table 
--	Create a table of "string digits" to assemble integers with 
DECLARE @Chars Table ( val	Char(1) )
INSERT @Chars Values ('1')
INSERT @Chars Values ('2')
INSERT @Chars Values ('3') 
INSERT @Chars Values ('4') 
INSERT @Chars Values ('5') 
INSERT @Chars Values ('6') 
INSERT @Chars Values ('7') 
INSERT @Chars Values ('8') 
INSERT @Chars Values ('9') 
INSERT @Chars Values ('0')
-- Generate Integer Dimision table
DECLARE @IntDim Table ( val INT )
INSERT @IntDim 
SELECT c1.Val + c2.Val + c3.Val + c4.Val + c5.Val
FROM @Chars c1	
CROSS JOIN @Chars c2  
CROSS JOIN @Chars c3  
CROSS JOIN @Chars c4 
CROSS JOIN @Chars c5   
WHERE  CONVERT(INT, c1.Val + c2.Val + c3.Val + c4.Val + c5.Val) between 1 AND @Payments -- Limit table to number of payments
-- End of Integer Dim table (Real sp code starts here) 
DECLARE @TotalCnts			INT  
,@GrandTotalCnts	INT 
,@TotalTaxCnts		INT
-- Change to integer since mudulo expects and returns integer		
SET @TotalCnts = @Total * 100
SET @GrandTotalCnts = ((@Total * @Tax) + @Total) * 100
SET @TotalTaxCnts = (@Total * @Tax) * 100
-- Insert records in single insert statement
INSERT dbo.tmp_Payments (ID, PreTaxPayment, TaxAmount, TotalPayment)
SELECT
ROW_NUMBER() OVER(order by @Payments) as ID 
,CASE i.val	
WHEN @Payments THEN ((@TotalCnts / @Payments) + (@TotalCnts % @Payments)) / 100.00	
ELSE (@TotalCnts / @Payments) / 100.00  
END as Payment
,CASE i.val WHEN @Payments THEN ((@TotalTaxCnts / @Payments) + (@TotalTaxCnts % @Payments)) / 100.00 
ELSE (@TotalTaxCnts / @Payments) / 100.00 
END as Tax
,CASE i.Val 
WHEN @Payments THEN ((@GrandTotalCnts / @Payments) + (@GrandTotalCnts % @Payments)) / 100.00 
ELSE (@GrandTotalCnts / @Payments) / 100.00 
END as TotalPayment
FROM @IntDim i
END 
GO 
-- USAGE: 
BEGIN TRAN
DECLARE 
@Total DECIMAL(32,2)
,@Tax DECIMAL(3,3)
,@Payments INT
SET @Total = 106
SET @Tax = .06
SET @Payments = 3 
EXEC usp_Payments_INS
@Total	= @Total
,@Tax = @Tax
,@Payments = @Payments
SELECT 
SUM(T1.PreTaxPayment) 
,SUM(T1.TaxAmount)
,@Total * @Tax
,SUM(T1.TotalPayment)
,(@Total * @Tax) + @Total
FROM tmp_Payments T1
ROLLBACK TRAN	
GO 
-- USAGE: 
BEGIN TRAN
DECLARE 
@Total DECIMAL(32,2)
,@Tax DECIMAL(3,3)
,@Payments INT
SET @Total = 1
SET @Tax = .12
SET @Payments = 20 
EXEC usp_Payments_INS
@Total	= @Total
,@Tax = @Tax
,@Payments = @Payments
SELECT 
SUM(T1.PreTaxPayment) 
,SUM(T1.TaxAmount)
,@Total * @Tax
,SUM(T1.TotalPayment)
,(@Total * @Tax) + @Total
FROM tmp_Payments T1
ROLLBACK TRAN	
GO 
-- USAGE -- Ver large number: 
BEGIN TRAN
DECLARE 
@Total DECIMAL(32,2)
,@Tax DECIMAL(3,3)
,@Payments INT
SET @Total = 1897279.65
SET @Tax = .25
SET @Payments = 234 
EXEC usp_Payments_INS
@Total	= @Total
,@Tax = @Tax
,@Payments = @Payments
SELECT 
SUM(T1.PreTaxPayment) 
,SUM(T1.TaxAmount)
,@Total * @Tax
,SUM(T1.TotalPayment)
,(@Total * @Tax) + @Total
FROM tmp_Payments T1
ROLLBACK TRAN	
GO

Chad, like most of our participants, missed the last requirement which states, "any remainder should be evenly split among all payment amounts, with the final payment amount reduced accordingly."  Sorry guys, meeting requirements is priority number 1.  Regardless of who won, it is great to see all of you taking an interest in our challenges and we look forward to receiving your submittals for our August Code Challenge.  Which, by the way, should be posted in the next day or two.  

If you have any comments or need clarification on something, let me know.  Greg B. your prize is on its way!! 

 

Share or Bookmark this post…
  • del.icio.us
  • Furl
  • LinkedIn
  • Technorati
  • TwitThis
  • StumbleUpon
  • Sphinn
  • Reddit
  • Propeller
  • NewsVine
  • Mixx
  • Ma.gnolia
  • Google
  • Facebook
  • DZone
  • Digg
  • DotNetKicks

July's Code Challenge

by Dan Murphy July 1, 2009 17:27 - commentComments (0)

The July Coding Challenge has been released. 

Last month's Coding Challenge was a flavor not many of you liked so this month we are switching it up.  We are bringing a rich, smooth SQL Server flavor with a hint of Stored Proc.  I think you all will enjoy!  Good luck!

Share or Bookmark this post…
  • del.icio.us
  • Furl
  • LinkedIn
  • Technorati
  • TwitThis
  • StumbleUpon
  • Sphinn
  • Reddit
  • Propeller
  • NewsVine
  • Mixx
  • Ma.gnolia
  • Google
  • Facebook
  • DZone
  • Digg
  • DotNetKicks

We Have a Winner - June Code Challenge

by Dan Murphy June 26, 2009 16:07 - commentComments (0)

Thank Buddha it is Friday!!

Alright kids, this is the moment that all of you guys have been waiting for.  We have received over 15 submittals on our June Code Challenge.  We (when I say We I mean the smart nerdy guys at igNew, not me) have evaluated all of submittals and have come up with a winner.  Before I spill the beans let me thank everyone who participated, who thought about participating, who stopped participating after over complicating the problem but gave it a try and everyone else who wanted to submit a SQL response....you know who you are.  

At this time I want to congratulate Carson M. for winning this month's Code Challenge.  A $25 gift certificate to ThinkGeek is on it's way to you now. Carson's answer was chosen as the best of the bunch.  His very simple and elegant solution works exactly as desired.  Extra points were given for a great comment explaining his solution as well as a descriptive function name.  Here is his solution. 

 

/*
* Takes the input splits it into an array for each character. 
* That array is then reversed and joined back together for
* each character as a string. The string is split once again 
* by ',' and sorted. A final join returns the string in the
* correct format with commas between each word.
*/
function reverse_and_sort(input) 
{ 
  return input.split('').reverse().join('').split(',').sort().join(','); 
} 

Make sure to check back on the 1st of July for our next Challenge.  We are coming up with another set of ambiguous and simple instructions for you to get frustrated with and this time around we will be using SQL.  Again, thanks for playing and congrats Carson!

Share or Bookmark this post…
  • del.icio.us
  • Furl
  • LinkedIn
  • Technorati
  • TwitThis
  • StumbleUpon
  • Sphinn
  • Reddit
  • Propeller
  • NewsVine
  • Mixx
  • Ma.gnolia
  • Google
  • Facebook
  • DZone
  • Digg
  • DotNetKicks