Sort Challenge !!!
Select messages from
# through # FAQ
[/[Print]\]

MVSFORUMS.com -> Mainframe Challenge

#1: Sort Challenge !!! Author: PhantomLocation: The Blue Planet PostPosted: Thu Nov 25, 2004 5:06 am
    —
Hi,

Here is a small SORT challenge for all of you. Actually my friend asked this question to me. I already completed this. I will post my solution later.The challenge is open. You can give solution in any Sort Product (DFSORT/Syncsort /CA-sort).


I have a input file as shown below.
Code:

250
1000
657
9800
12
567
700


The input file layout is: (LRECL=80, RECFM=FB)
FIELD1 PIC X(04)
FILLER PIC X(76)

The Output should look like this: You should group 3 records at a time and the 3 FIELD1 should come in one line.
Code:

250  1000 657
9800 12   567
700


This should be accomplished in MINIMUM no. of Steps & Passes.

Good Luck,

Thanks,
Phantom

#2:  Author: PhantomLocation: The Blue Planet PostPosted: Tue Nov 30, 2004 1:09 am
    —
Hi All,

Its really surprising to see that there are no responses to this thread yet.
The challenge is still open. You can give solutions in syncsort/Dfsort. I will post my solution tomorrow.

I would like everyone to try their best.

Good Luck,
Phantom

#3: Sort Challenge !!! Author: LRDevulapalli PostPosted: Tue Nov 30, 2004 7:21 am
    —
Phantom,

I have done this using DFSORT ICETOOL SAMPLE feature.
Code:

//STEP030 EXEC PGM=ICETOOL,COND=(4,LT)                   
//STEPLIB   DD DSN=SYS1.SYSTEMS.XANTH.LINKLIB,DISP=SHR   
//          DD DSN=SYS1.SICELPA,DISP=SHR                 
//          DD DSN=SYS1.SICELINK,DISP=SHR                 
//TOOLMSG   DD SYSOUT=*                                   
//DFSMSG    DD SYSOUT=*                                   
//SYSOUT    DD SYSOUT=*                                   
//INFL1     DD DSN=input file,DISP=SHR     
//TEMPFL1   DD DSN=&&TEMPFL1,                             
//             DISP=(MOD,PASS),UNIT=SYSDA,               
//             SPACE=(CYL,(1,1),RLSE),                   
//             DCB=*.INFL1                               
//OUTFL1    DD DSN=output file,
//             DISP=(,CATLG,DELETE),UNIT=SYSDA,           
//             SPACE=(CYL,(1,1),RLSE),                   
//             DCB=*.INFL1                               
//SORTWK01  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)       
//SORTWK02  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)       
//SORTWK03  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)       
//SORTWK04  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)         
//SORTWK05  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)         
//SORTWK06  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)         
//SORTWK07  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)         
//SORTWK08  DD UNIT=SYST,SPACE=(CYL,(5,5),,CONTIG)         
//*                                                         
//TOOLIN    DD *                                           
  COPY FROM(INFL1)          USING(CTL1)                     
  COPY FROM(INFL1)          USING(CTL2)                     
  COPY FROM(INFL1)          USING(CTL3)                     
  SPLICE FROM(TEMPFL1) TO(OUTFL1) ON(81,8,ZD) WITHEACH -   
  WITH(5,4) WITH(9,4) USING(CTL4)                       
/*                                                         
//*                                                         
//CTL1CNTL  DD *                                           
  OPTION COPY                                               
  OUTFIL FNAMES=TEMPFL1,STARTREC=1,SAMPLE=(3,1),           
  OUTREC=(1,4,76X,81:SEQNUM,8,ZD)                     
/*                                                         
//CTL2CNTL  DD *                                           
  OPTION COPY                                             
  OUTFIL FNAMES=TEMPFL1,STARTREC=2,SAMPLE=(3,1),           
  OUTREC=(4X,5:1,4,72X,81:SEQNUM,8,ZD)             
/*                                                         
//CTL3CNTL  DD *                                           
  OPTION COPY                                             
  OUTFIL FNAMES=TEMPFL1,STARTREC=3,SAMPLE=(3,1),           
  OUTREC=(8X,9:1,4,62X,81:SEQNUM,8,ZD)                 
/*                                                         
//CTL4CNTL  DD *                                           
  OUTFIL FNAMES=OUTFL1,OUTREC=(1,4,1X,5,4,1X,9,4,66X)
/*

#4:  Author: kolusuLocation: San Jose PostPosted: Tue Nov 30, 2004 8:24 am
    —
LRDevulapalli,

You don't need 4 passes to achieve the data. I don't have DFSORT at my shop,so cannot test it. But here is the untested version of DFSORT using SAMPLE & SPLICE parms. You also need KEEPNODUPS parm on the Splice parm to keep records which do not have matching record to splice.

Code:

//STEP0100 EXEC PGM=ICETOOL
//TOOLMSG  DD SYSOUT=*
//DFSMSG   DD SYSOUT=*
//IN       DD *
250
1000
657
9800
12
567
700
//T1       DD DSN=&T1,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)   
//T2       DD DSN=&T2,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)   
//T3       DD DSN=&T3,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)   
//CON      DD DSN=&T1,DISP=OLD,VOL=REF=*.T1                 
//         DD DSN=&T2,DISP=OLD,VOL=REF=*.T2                 
//         DD DSN=&T3,DISP=OLD,VOL=REF=*.T3
//OUT      DD SYSOUT=*
//TOOLIN   DD *                                                     
  COPY FROM(IN)  USING(CTL1)                                         
  SPLICE FROM(CON) TO(OUT) ON(81,8,ZD) KEEPNODUPS  WITHEACH -       
  WITH(5,4) WITH(9,4) USING(CTL2)                                   
//CTL1CNTL DD *
  OUTFIL FNAMES=T1,STARTREC=1,SAMPLE=(3,1),
  OUTREC=(1,4,76X,81:SEQNUM,8,ZD)
  OUTFIL FNAMES=T2,STARTREC=2,SAMPLE=(3,1),
  OUTREC=(4X,5:1,4,72X,81:SEQNUM,8,ZD)
  OUTFIL FNAMES=T3,STARTREC=3,SAMPLE=(3,1),
  OUTREC=(8X,9:1,4,62X,81:SEQNUM,8,ZD)
//CTL2CNTL DD *
  OUTFIL FNAMES=OUT,OUTREC=(1,4,X,5,4,X,9,4,80:X)
/*


Kolusu

#5:  Author: PhantomLocation: The Blue Planet PostPosted: Wed Dec 01, 2004 1:35 am
    —
Okay.....I have got 6 solutions from 5 people. And surprisingly all 6 are different. Two of these are already posted (one by LRDevulapalli and Kolusu's reply to that post).

Here are the remaining 4. Please feel free to give your Suggestions/Comments.

Solution 1: From the requestor of this Challenge - my Colleague
Code:

//R010     EXEC PGM=SORT                               
//SYSOUT   DD SYSOUT=*                               
//SYSPRINT DD SYSOUT=*                               
//DFSMSG   DD SYSOUT=*                               
//SORTIN   DD DISP=SHR,DSN=MY.INPUT.FILE     
//SORTOF01 DD DISP=SHR,DSN=MY.TEMP.FILE1         
//SORTOF02 DD DISP=SHR,DSN=MY.TEMP.FILE2       
//SORTOF03 DD DISP=SHR,DSN=MY.TEMP.FILE3       
//SYSIN DD *                                         
  OPTION COPY                                       
  OUTFIL FILES=(01,02,03),SPLIT                     
/*                                     
//*
//*             
//R020     EXEC PGM=SYNCTOOL                         
//TOOLMSG   DD SYSOUT=*                                   
//DFSMSG    DD SYSOUT=*                                   
//IN1      DD DSN=MY.TEMP.FILE1,DISP=SHR             
//IN2      DD DSN=MY.TEMP.FILE2,DISP=SHR             
//IN3      DD DSN=MY.TEMP.FILE3,DISP=SHR             
//T1       DD  DSN=&T1,DISP=(,PASS)                       
//T2       DD  DSN=&T2,DISP=(,PASS)                       
//T3       DD  DSN=&T3,DISP=(,PASS)                       
//INTF    DD  DSN=&T1,VOL=REF=*.T1,DISP=(OLD,PASS)       
//           DD  DSN=&T2,VOL=REF=*.T2,DISP=(OLD,PASS)       
//           DD  DSN=&T3,VOL=REF=*.T3,DISP=(OLD,PASS)       
//OUT      DD  SYSOUT=*                                   
//TOOLIN   DD  *                                         
  COPY FROM(IN1) TO(T1) USING(CTL1)                       
  COPY FROM(IN2) TO(T2) USING(CTL2)                       
  COPY FROM(IN3) TO(T3) USING(CTL3)                       
  SORT FROM(INTF) TO(OUT) USING(CTL4)                     
//CTL1CNTL DD  *                                         
  OUTREC FIELDS=(1:1,4,X,C'0',4X,C'0',72:X,73:SEQNUM,8,ZD)
//CTL2CNTL DD  *                                             
  OUTREC FIELDS=(C'0',4X,6:1,4,C'0',72:X,73:SEQNUM,8,ZD)     
//CTL3CNTL DD  *                                             
  OUTREC FIELDS=(C'0',4X,C'0',4X,11:1,4,72:X,73:SEQNUM,8,ZD) 
//CTL4CNTL DD  *                                             
  SORT FIELDS=(73,8,CH,A)                                     
  SUM FIELDS=(1,1,ZD,6,1,ZD,11,1,ZD)                         
  OUTREC FIELDS=(1:1,72,8X)                                   
//*     


Comments:
Quote:
This solution took 2 Steps and 5 passes over the input file. It also required 6 temporary files to get to the result. The developer used the OUTFIL SPLIT option to a good extent to split the records easily across three temp files, but he took 5 passes of the input.



Solution 2: from my another colleague
Code:

//R010   EXEC PGM=SORT                                   
//SYSPRINT DD SYSOUT=*                                   
//SORTIN DD DSN=MY.INPUT.FILE,DISP=SHR             
//SORTOUT DD DSN=MY.TEMP.FILE1.R010,DISP=SHR           
//SYSIN DD *                                             
    INREC FIELDS=(SEQNUM,4,ZD,START=0,INCR=1,           
                   SEQNUM,4,ZD,START=0,INCR=1,1,4)       
    SORT FIELDS=COPY                                     
    OUTREC FIELDS=(1,4,ZD,SUB,((1,4,ZD,DIV,+3),MUL,+3), 
                   5,4,ZD,DIV,+3,9,4)                   
//SYSOUT DD SYSOUT=*                                     
//*
//*
//R020    EXEC PGM=SORT                                   
//SYSPRINT DD SYSOUT=*                                   
//SORTIN DD DSN=MY.TEMP.FILE1.R010,DISP=SHR           
//OUT1    DD DSN=MY.TEMP.FILE1.R020,DISP=SHR         
//OUT2    DD DSN=MY.TEMP.FILE2.R020,DISP=SHR                     
//OUT3    DD DSN=MY.TEMP.FILE3.R020,DISP=SHR                     
//SYSIN DD *                                                       
    SORT FIELDS=COPY                                               
    OUTFIL FNAMES=OUT1,INCLUDE=(1,15,FS,EQ,0),                     
                       OUTREC=(16,16,33,4,FS,ZD,C'00000000',52X)   
    OUTFIL FNAMES=OUT2,INCLUDE=(1,15,FS,EQ,1),                     
                       OUTREC=(16,16,C'0000',33,4,FS,ZD,C'0000',52X)
    OUTFIL FNAMES=OUT3,INCLUDE=(1,15,FS,EQ,2),                     
                       OUTREC=(16,16,C'00000000',33,4,FS,ZD,52X)   
//SYSOUT DD SYSOUT=*                                               
//*
//*
//R030   EXEC PGM=SORT                                               
//SYSPRINT DD SYSOUT=*                                             
//SORTIN  DD DSN=MY.TEMP.FILE1.R020,DISP=SHR                     
//        DD DSN=MY.TEMP.FILE2.R020,DISP=SHR                     
//        DD DSN=MY.TEMP.FILE3.R020,DISP=SHR                     
//SORTOUT DD DSN=MY.OUTPUT.FILE,DISP=SHR                     
//SYSIN DD *                                                       
    SORT FIELDS=(1,16,FS,A)                                         
    SUM FIELDS=(17,4,ZD,21,4,ZD,25,4,ZD)                             
    OUTREC FIELDS=(17,4,ZD,EDIT=(IIII),X,21,4,ZD,EDIT=(IIII),X,25,4,
                 ZD,EDIT=(IIII))                                     
//SYSOUT DD SYSOUT=*                                                 


Comments:
Quote:
This solution took 3 Steps, 3 passes & 4 Temporary files to get to the result. The First 2 steps could have been easily merged into 1 using OUTFIL SPLIT parameters in the same step.



Solution 3: from Kolusu
Code:

//R001     EXEC PGM=SYNCTOOL                     
//DFSMSG   DD SYSOUT=*                           
//TOOLMSG  DD SYSOUT=*                           
//INPUT    DD *                                   
100                                               
5500                                             
2000                                             
25                                               
250                                               
0001                                             
809                                               
790                                               
/*                                               
//L1       DD DSN=&&T1,DISP=(,PASS)               
//L2       DD DSN=&&T2,DISP=(,PASS)               
//L3       DD DSN=&&T3,DISP=(,PASS)               
//CON    DD DSN=&&T1,DISP=SHR,VOL=REF=*.L1     
//           DD DSN=&&T2,DISP=SHR,VOL=REF=*.L2     
//           DD DSN=&&T3,DISP=SHR,VOL=REF=*.L3     
//OUT      DD SYSOUT=*                           
//TOOLIN   DD *                                                 
  COPY FROM(INPUT) USING(CTL1)                                 
  SORT FROM(CON)  TO(OUT)  USING(CTL2)                         
/*                                                             
//CTL1CNTL DD *                                                 
  INREC FIELDS=(1,80,SEQNUM,8,ZD,START=4,INCR=1)               
  SORT FIELDS=COPY                                             
  OUTREC FIELDS=(01,80,                                         
                 81,8,ZD,SUB,(+3,MUL,(81,8,ZD,DIV,+3)),EDIT=(T))
  OUTFIL FNAMES=L1,INCLUDE=(81,1,CH,EQ,C'1'),                   
             OUTREC=(1,4,10Z,80:X,SEQNUM,8,ZD)                             
  OUTFIL FNAMES=L2,INCLUDE=(81,1,CH,EQ,C'2'),                   
             OUTREC=(5Z,1,4,5Z,80:X,SEQNUM,8,ZD)                           
  OUTFIL FNAMES=L3,INCLUDE=(81,1,CH,EQ,C'0'),                   
             OUTREC=(10Z,1,4,80:X,SEQNUM,8,ZD)                             
/*                                                             
//CTL2CNTL DD *                                                 
  OPTION EQUALS                                                 
  SORT FIELDS=(81,8,CH,A)                                       
  SUM FIELDS=(5,4,9,4,13,2),FORMAT=BI                           
  OUTREC FIELDS=(1,80)           
/*                               


Comments:
Quote:
The first two solutions was written to handle only numeric data, since the developers used ZD summation to merge the records. Kolusu's solution is more generic. It supports Numeric as well as non-numeric data in the input file. Solution 2 is a bit similar to this but Kolusu's one is more efficient since the no. of passes required is just 2.



Solution 4: My solution
Code:

//R001     EXEC PGM=SYNCTOOL               
//DFSMSG   DD SYSOUT=*                     
//TOOLMSG  DD SYSOUT=*                     
//INPUT    DD *                             
0001                                       
0002                                       
0003                                       
0004                                       
0005                                       
0006                                       
0007                                       
0008                                       
0009                                       
0010                                           
0011                                           
0012                                           
0013                                           
0014                                           
0015                                           
0016                                           
0017                                           
0018                                           
0019                                           
0020                                           
/*                                             
//TEMP     DD DSN=&&T1,DISP=(,PASS)           
//OUT      DD SYSOUT=*                         
//TOOLIN   DD *                               
  COPY FROM(INPUT) TO(TEMP) USING(CTL1)       
  SORT FROM(TEMP)  TO(OUT)  USING(CTL2)       
/*                                             
//CTL1CNTL DD *                               
  INREC FIELDS=(1,4,                                             
                SEQNUM,8,ZD,START=0)                             
  OUTREC FIELDS=(1,4,                                           
                 5,8,ZD,SUB,(5,8,ZD,DIV,+3),MUL,+3,EDIT=(TTTT), 
                 5,8,ZD,DIV,+3,EDIT=(TTTTTTTT))                 
  OUTFIL OUTREC=(5,4,CHANGE=(4,X'F0F0F0F1',X'00000000',         
                               X'F0F0F0F2',X'00000000'),         
                    NOMATCH=(1,4),X,                             
                 5,4,CHANGE=(4,X'F0F0F0F0',X'00000000',         
                               X'F0F0F0F2',X'00000000'),         
                    NOMATCH=(1,4),X,                             
                 5,4,CHANGE=(4,X'F0F0F0F0',X'00000000',         
                               X'F0F0F0F1',X'00000000'),         
                    NOMATCH=(1,4),X,9,8,80:X)                   
/*                                                               
//CTL2CNTL DD *                                                 
  SORT FIELDS=(16,8,ZD,A)                                       
  SUM FIELDS=(1,4,BI,6,4,BI,11,4,BI)                             
  OUTREC FIELDS=(1,15,80:X)                                     
/*   


Brief Overview of my solution:
Code:
The solution takes 1 step, 2 passes and just 1 Temp. file to achieve the desired result. 

Pass # 1:
---------
a. Use INREC to Insert a 8 digit sequence number (starting at 00000000) at the end of the record layout.
b. In OUTREC, use arithmetic operators over the Sequence no. field and generate two different types of sequence nos in the record.

   5,8,ZD,SUB,(5,8,ZD,DIV,+3),MUL,+3,EDIT=(TTTT) - This will generate a set of numbers in the sequence 0000, 0001, 0002, 0000, 0001, 0002, 0000 and so on.  (Basically this is similar to using MOD operator).

   5,8,ZD,DIV,+3,EDIT=(TTTTTTTT) - This will produce a set of numbers in the sequence 00000000, 00000000, 00000000, 00000001, 00000001, 00000001, 00000002 & so on.  This is used to group 3 records together in the next pass.

Output of OUTREC will be as shown below:
----+----1----+----2
0001000000000000   
0002000100000000   
0003000200000000   
0004000000000001   
0005000100000001   
0006000200000001   
0007000000000002   
0008000100000002   
0009000200000002   
0010000000000003   
0011000100000003   
0012000200000003   
0013000000000004   
0014000100000004   
0015000200000004   
0016000000000005   
0017000100000005   
0018000200000005   
0019000000000006   
0020000100000006   

c. The final OUTFIL OUTREC statement uses CHANGE operator to reformat the input record depending on the seqnum at position 5 to 8.
   If 5 to 8 contains 0000, then convert the record as <4 char data> <space> <4 low-value> <space> <4 low-value> <space> <seqnum 2>
   If 5 to 8 contains 0001, then convert the record as <4 low-value> <space> <4 char data> <space> <4 low-value> <space> <seqnum 2>
   If 5 to 8 contains 0002, then convert the record as <4 low-value> <space> <4 low-value> <space> <4 char data> <space> <seqnum 2>

----+----1----+----2----+
0001           00000000 
     0002      00000000 
          0003 00000000 
0004           00000001 
     0005      00000001 
          0006 00000001 
0007           00000002 
     0008      00000002 
          0009 00000002 
0010           00000003 
     0011      00000003 
          0012 00000003 
0013           00000004 
     0014      00000004 
          0015 00000004 
0016           00000005 
     0017      00000005 
          0018 00000005 
0019           00000006 
     0020      00000006 


Pass # 2:
---------
a. Sort the records on the seqnum order (at Pos 16 to 23) so that 3 records are grouped at a time.
b. Sum the data portion (1,4, 6,4 and 11,4) using BI summation so that the records are merged together.
c. Strip off the seqnum before writing to output.


Suggestions/Comments are most welcome.

Thanks,
Phantom

#6:  Author: kolusuLocation: San Jose PostPosted: Wed Dec 01, 2004 6:20 am
    —
Phantom,

Here are 2 other possible solutions. DFSORT has the function MOD which can be used to get remainder directly instead of calculating it.

Code:

//STEP0100 EXEC PGM=ICETOOL                                     
//TOOLMSG  DD SYSOUT=*                                         
//DFSMSG   DD SYSOUT=*                                         
//IN       DD *                                                 
250                                                             
1000                                                           
657                                                             
9800                                                           
12                                                             
567                                                             
700                                                             
//L1       DD DSN=&L1,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)       
//L2       DD DSN=&L2,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)       
//L3       DD DSN=&L3,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)       
//CON      DD DSN=&L1,DISP=OLD,VOL=REF=*.L1                     
//         DD DSN=&L2,DISP=OLD,VOL=REF=*.L2                     
//         DD DSN=&L3,DISP=OLD,VOL=REF=*.L3                     
//OUT      DD SYSOUT=*                                         
//TOOLIN   DD *                                                 
  COPY FROM(IN)  USING(CTL1)                                   
  SPLICE FROM(CON) TO(OUT) ON(81,8,ZD) KEEPNODUPS  WITHEACH -   
  WITH(6,5) WITH(11,5) USING(CTL2)                             
//CTL1CNTL DD *                                                 
  INREC FIELDS=(1,80,SEQNUM,8,ZD,START=4,INCR=1)               
  OUTREC FIELDS=(1,80,81,8,ZD,MOD,+3,TO=ZD,LENGTH=1)   
  OUTFIL FNAMES=L1,INCLUDE=(81,1,CH,EQ,C'1'),                   
  OUTREC=(1,5,80:X,SEQNUM,8,ZD)                                 
  OUTFIL FNAMES=L2,INCLUDE=(81,1,CH,EQ,C'2'),                   
  OUTREC=(5X,1,5,80:X,SEQNUM,8,ZD)                             
  OUTFIL FNAMES=L3,INCLUDE=(81,1,CH,EQ,C'0'),                   
  OUTREC=(10X,1,5,80:X,SEQNUM,8,ZD)                             
//CTL2CNTL DD *                                                 
  OUTFIL FNAMES=OUT,OUTREC=(1,80)                               
/*


This solution is slightly different from your solution. We directly use the character values in the change parm as the merging of the records is done by SPLICE parm.
Code:

//STEP0100 EXEC PGM=ICETOOL                                     
//TOOLMSG  DD SYSOUT=*                                         
//DFSMSG   DD SYSOUT=*                                         
//IN       DD *                                                 
250                                                             
1000                                                           
657                                                             
9800                                                           
12                                                             
567                                                             
700                                                         
//T1       DD DSN=&T1,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)   
//OUT      DD SYSOUT=*                                       
//TOOLIN   DD *                                             
  COPY FROM(IN)  USING(CTL1)                                 
  SPLICE FROM(T1) TO(OUT) ON(81,1,ZD) KEEPNODUPS  WITHEACH -
  WITH(6,5) WITH(11,5) USING(CTL2)                           
//CTL1CNTL DD *                                             
  INREC FIELDS=(1,4,                                       
                SEQNUM,8,ZD,START=0)                       
  OUTREC FIELDS=(1,4,                                       
                 5,8,ZD,SUB,(5,8,ZD,DIV,+3),MUL,+3,EDIT=(T),
                 5,8,ZD,DIV,+3,EDIT=(T))                   
  OUTFIL FNAMES=T1,
  OUTREC=(5,1,CHANGE=(4,C'1',C'    ',     
                        C'2',C'    '),               
                        NOMATCH=(1,4),X,                       
          5,1,CHANGE=(4,C'0',C'    ',               
                        C'2',C'    '),               
                        NOMATCH=(1,4),X,                       
          5,1,CHANGE=(4,C'0',C'    ',               
                        C'1',C'    '),               
                        NOMATCH=(1,4),X,80:X,6,1)               
//CTL2CNTL DD *                                             
  OUTFIL FNAMES=OUT,OUTREC=(1,80)                           
/*


Kolusu

#7:  Author: PhantomLocation: The Blue Planet PostPosted: Wed Dec 01, 2004 6:34 am
    —
Kolusu,

One more solution. Basically derived from what u gave me. Wink

Using 1 MOD operator instead of SUB,DIV,MUL group of operations.

Code:

//STEP0100 EXEC PGM=ICETOOL                                     
//TOOLMSG  DD SYSOUT=*                                         
//DFSMSG   DD SYSOUT=*                                         
//IN       DD *                                                 
250                                                             
1000                                                           
657                                                             
9800                                                           
12                                                             
567                                                             
700                                                         
//T1       DD DSN=&T1,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)   
//OUT      DD SYSOUT=*                                       
//TOOLIN   DD *                                             
  COPY FROM(IN)  USING(CTL1)                                 
  SPLICE FROM(T1) TO(OUT) ON(81,1,ZD) KEEPNODUPS  WITHEACH -
  WITH(6,5) WITH(11,5) USING(CTL2)                           
//CTL1CNTL DD *                                             
  INREC FIELDS=(1,4,                                       
                SEQNUM,8,ZD,START=0)                       
  OUTREC FIELDS=(1,4,                                       
                 5,8,ZD,MOD,+3,TO=ZD,LENGTH=1,
                 5,8,ZD,DIV,+3,EDIT=(T))                   
  OUTFIL FNAMES=T1,
  OUTREC=(5,1,CHANGE=(4,C'1',C'    ',     
                        C'2',C'    '),               
                        NOMATCH=(1,4),X,                       
          5,1,CHANGE=(4,C'0',C'    ',               
                        C'2',C'    '),               
                        NOMATCH=(1,4),X,                       
          5,1,CHANGE=(4,C'0',C'    ',               
                        C'1',C'    '),               
                        NOMATCH=(1,4),X,80:X,6,1)               
//CTL2CNTL DD *                                             
  OUTFIL FNAMES=OUT,OUTREC=(1,80)                           
/*


Thanks,
Phantom

#8:  Author: Danav PostPosted: Sat Dec 11, 2004 10:09 am
    —
I tried the following in on estep and is working.

Although the I/P file has a record length of 80, I am enforcing a length of 240 in I/P parameters so that it picks up 3 records at a time and then sort takes the 1st 4 characters and next 4 from 81st byte (i.e. first 4 characters of 2nd record) and then from 240th byte keeping the rest 68 bytes in O/P as spaces.



Code:
//STEP01  EXEC PGM=SYNCSORT                         
//SYSOUT  DD SYSOUT=*                               
//SORTIN  DD DSN=INPUT DATASET,     
//        DCB=(RECFM=FB,LRECL=240,BLKSIZE=27840),   
//        DISP=SHR                                   
//SORTOUT DD DSN=OUTPUT DATASET,     
//        DISP=(NEW,CATLG,DELETE),                 
//        DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),         
//        SPACE=(CYL,(100,100),RLSE)             
//SYSIN   DD *                                       
  SORT FIELDS=COPY                                   
 OUTREC FIELDS=(1:1,4,5:81,4,9:161,4,13:68X)         
/*                                                   



Thanks,
Danav.

#9:  Author: coolmanLocation: US PostPosted: Sat Dec 11, 2004 11:05 am
    —
Danav,

Your solution would work only if the total no. of records in the file is a multiple of 3. Otherwise, it wud fail.

Cheers,
Coolman

#10:  Author: PhantomLocation: The Blue Planet PostPosted: Sun Dec 12, 2004 2:36 am
    —
Danav,

Excellent!!!. Though your solution has a limitation on the input file record count, it is good for everyone to the different possible alternatives. Probably your solution could turn very handy in some special cases. Its always good to think in 'n' different ways !!!.

Thanks,
Phantom

#11:  Author: kolusuLocation: San Jose PostPosted: Mon Dec 13, 2004 5:06 am
    —
Quote:

Though your solution has a limitation on the input file record count, it is good for everyone to the different possible alternatives.


Phantom,

There is another limitation for the solution provided by danav. The Blocksize should be a multiple of the lrecl you are trying to override.

Thanks

Kolusu

#12:  Author: PhantomLocation: The Blue Planet PostPosted: Mon Dec 13, 2004 5:19 am
    —
Kolusu,

Code:

The Blocksize should be a multiple of the lrecl you are trying to override.


Oh Okay... I didn't know this. I thought its enough to take care of the LRECL. Thanks for the info.

Regards,
Phantom

#13:  Author: Frank YaegerLocation: San Jose PostPosted: Sat Dec 25, 2004 2:02 pm
    —
Below is a DFSORT solution with only one sort pass and no temporary files that can handle numerics and non-numerics. It uses the new IFTHEN and OVERLAY features available with z/OS DFSORT V1R5 PTF UQ95214 and DFSORT R14 PTF UQ95213.

Note that both IFTHEN and OVERLAY can be used to do multiple operations on each record, and earlier changes affect later changes. For example:

INREC statement:
In the OVERLAY for WHEN=INIT, we set up the seqnum and then use MOD on the seqnum to get 0, 1 or 2. We then use the 0, 1 or 2 in subsequent IFTHEN clauses all within the same INREC statement before we start sorting.

OUTREC statement:
In the first IFTHEN we use HIT=NEXT to continue with the second OUTREC IFTHEN for all records so we can handle binary zeros in 6-9 AND in 11-14.

It's pretty amazing what you can do in one pass using IFTHEN.

Code:

//S1 EXEC PGM=ICEMAN
//SYSOUT  DD SYSOUT=*
//SORTIN       DD *
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
AAAA
BBBB
/*
//SORTOUT DD SYSOUT=*
//SYSIN   DD *
  OPTION EQUALS
* Init. records to:
  INREC IFTHEN=(WHEN=INIT,
* aaaa zzzz zzzz ... 00000001
* bbbb zzzz zzzz ... 00000002
* cccc zzzz zzzz ... 00000003
* dddd zzzz zzzz ... 00000004
* eeee zzzz zzzz ... 00000005
* ffff zzzz zzzz ... 00000006
* ...
* where zzzz is 4 binary zeros.
     OVERLAY=(6:4Z,11:4Z,81:SEQNUM,8,ZD,START=0,
* Use MOD to convert seqnum to 0, 1 or 2 to get:
* aaaa zzzz zzzz ... 0
* bbbb zzzz zzzz ... 1
* cccc zzzz zzzz ... 2
* dddd zzzz zzzz ... 0
* eeee zzzz zzzz ... 1
* ffff zzzz zzzz ... 2
* ...
              81:81,8,ZD,MOD,+3,TO=ZD,LENGTH=1)),
* Set seqnum for 0 records to get:
* aaaa zzzz zzzz ... 00000001
* dddd zzzz zzzz ... 00000002
* ...
   IFTHEN=(WHEN=(81,1,CH,EQ,C'0'),
     OVERLAY=(81:SEQNUM,8,ZD)),
* Set seqnum for 1 records and reformat to get:
* zzzz bbbb zzzz ... 00000001
* zzzz eeee zzzz ... 00000002
* ...
   IFTHEN=(WHEN=(81,1,CH,EQ,C'1'),
     OVERLAY=(6:1,4,1:4Z,81:SEQNUM,8,ZD)),
* Set seqnum for 2 records and reformat to get:
* zzzz zzzz cccc ... 00000001
* zzzz zzzz ffff ... 00000002
* ...
   IFTHEN=(WHEN=(81,1,CH,EQ,C'2'),
     OVERLAY=(11:1,4,1:4Z,81:SEQNUM,8,ZD))
* Sort on seqnum to get:
* aaaa zzzz zzzz ... 00000001
* zzzz bbbb zzzz ... 00000001
* zzzz zzzz cccc ... 00000001
* dddd zzzz zzzz ... 00000002
* zzzz eeee zzzz ... 00000002
* zzzz zzzz ffff ... 00000002
* ...
  SORT FIELDS=(81,8,ZD,A)
* SUM with binary zeros to get:
* aaaa bbbb cccc ... 00000001
* dddd eeee ffff ... 00000002
* ...
  SUM FORMAT=BI,FIELDS=(1,4,6,4,11,4)
* Replace binary zeros in 6-9 or 11-14 with blanks (takes care of
* record count that is not a multiple of 3).
  OUTREC IFTHEN=(WHEN=(6,4,BI,EQ,+0),OVERLAY=(6:4X),HIT=NEXT),
         IFTHEN=(WHEN=(11,4,BI,EQ,+0),OVERLAY=(11:4X)),
* Remove seqnum.
         IFOUTLEN=80
/*


Of course, you could use the same technique with COPY and SPLICE operators instead of doing the binary SUM trick, if you like.

For complete information on the new functions available with these DFSORT PTFs, see:

http://www.ibm.com/servers/storage/support/software/sort/mvs/pdug/index.html



MVSFORUMS.com -> Mainframe Challenge


output generated using printer-friendly topic mod. All times are GMT - 5 Hours

Page 1 of 1

Powered by phpBB © 2001, 2005 phpBB Group